ggplot2 パッケージでの地図出力でポイントとラベルの重なりを防ぐ方法
はじめに
ggplot2 パッケージを使って sf オブジェクトから地図を出力する際、ポイントで表される地物とそのラベルの両方を出力したいことがある。このとき何も考えないと、ポイントと点が重なってしまう。
例えば、以下の地図では横浜市の市役所・区役所のポイント(赤色)がそのラベルと重なってしまっている。

重ならないようにするには、ggrepel パッケージを使えば良い。

ggrepel パッケージは、sf オブジェクトの出力時以外でも、ggplot2 での重なりを防ぐために使うことができる。例えば、「ggplot2 パッケージによる可視化の際のラベルの重なりを防ぐ」には、散布図でのラベルの重なりを防いだ例が載っている。
今回使用するシェープファイル
今回は、国土交通省の国土数値情報から手に入る以下の2つのシェープファイルを用いる。
- 国土数値情報 行政区域データ のうち、平成26年(2014年)の「神奈川」のデータ ((ダウンロード対象となるファイルは、N03-140401_14_GML.zip))
- 国土数値情報 市区町村役場データ(第1.0版)のうち、平成26年(2014年)8月31日時点の「神奈川」のデータ ((ダウンロード対象となるファイルは、P34-14_14_GML.zip))
これらをダウンロードして展開しておく。これらのファイルは神奈川県の全自治体の情報が入っている。後ほど、R上で横浜市の部分だけ抽出することになる。
ポイントとラベルが重ならないように地図を出力するコード
R で、ポイントとラベルが重ならないように地図を出力するコードは以下の通り。
# 必要なパッケージの読み込み
library("tidyverse")
library("sf")
# 神奈川県の行政区域データ(ポリゴン)のシェープファイル読みこみ
yokohama_basemap <- read_sf("./N03-140401_14_GML/N03-14_14_140401.shp") %>%
filter(N03_003 == "横浜市") # 横浜市のデータのみ残す
# 神奈川県の市区町村役場データ(ポイント)のシェープファイル読みこみ
yokohama_gov <- read_sf("./P34-14_14_GML/P34-14_14.shp", options = c("ENCODING=CP932")) %>%
filter(str_starts(P34_004, "横浜市")) # 横浜市のデータのみ残す
# ggplot2 パッケージによる地図の出力
ggplot() +
# 横浜市の行政区(ポリゴン)の出力
geom_sf(data = yokohama_basemap) +
# 横浜市の市役所・区役所(ポイント)の出力
geom_sf(data = yokohama_gov,
colour = "red",
size = 1.5) +
# 横浜市の市役所・区役所の名称のラベルの出力
ggrepel::geom_text_repel(
data = yokohama_gov,
aes(label = P34_003, geometry = geometry),
stat = "sf_coordinates",
# ラベルの文字の大きさの設定
size = 3,
# ラベルからの引き出し線の設定
min.segment.length = 0,
segment.color = "gray50") +
theme_minimal()
上記のコードでは、まず必要なパッケージ ((tidyverse と sf の2つ。なお、地図を描く際は、ggplot2 パッケージを使っているが、このパッケージは idyverse を読みこむ際にいっしょに読みこまれる。)) を読みこんだ上で、ダウンロードしてきたシェープファイルを読みこんでいる。行政区域データの方は filter(N03_003 == "横浜市") で横浜市だけを抽出している。N03_003 列に市町村名が入っているので、これで横浜市だけ抽出できるのだ。また、市区町村役場データの方は filter(str_starts(P34_004, "横浜市")) で横浜市だけを抽出している。P34_004 列に役所の住所が「横浜市中区港町1-1」 ((この住所は2014年時点の横浜市役所の住所である。その後移転し、2022年現在は「横浜市中区本町6丁目50番地の10」にある。)) のように入っているので、冒頭が「横浜市」であるところを抽出しているのだ。
その後、コードの13行目(ggplot() +)以降で、地図を出力している。
- 15行目(
geom_sf(data = yokohama_basemap))で横浜市の行政区のポリゴンを出力。 - 17行目(
geom_sf(data = yokohama_gov,)から19行目までで、市役所・区役所の存在する地点に、赤いポイントを出力。 - 21行目(
ggrepel::geom_text_repel()から29行目で、市役所・区役所の名称のラベルを出力。ここでggrepelパッケージの機能を使い、重ならないようにしている。geometry = geometryというのは、図中に出力する位置は、yokohama_govの中のgeometry列の情報を使ってくださいという意味。stat = "sf_coordinates"は、sf オブジェクトの経度・緯度の情報を良いあんばいに取り出す方法を使います、という意味。geom_sf()関数ではデフォルトでstat = "sf_coordinates"となっているのでわざわざ書く必要がないのだが、ggrepel::geom_text_repel()関数ではデフォルトでないので明示が必要。
- 最後の
theme_minimal()で図のスタイルをシンプルなものにする。
参考:ポイントとラベルが重なった地図を出力するコード
最後に、参考までに、この記事の冒頭で挙げた地図、すなわちポイントとラベルが重なってしまっている地図を出力するコードを挙げておく。
# 必要なパッケージの読み込み
library("tidyverse")
library("sf")
# 神奈川県の市区町村(ポリゴン)のシェイプファイル読みこみ
yokohama_basemap <- read_sf("./N03-140401_14_GML/N03-14_14_140401.shp") %>%
filter(N03_003 == "横浜市") # 横浜市のデータのみ残す
# 神奈川県の市区町村役場等(ポイント)のシェイプファイル読みこみ
yokohama_gov <- read_sf("./P34-14_14_GML/P34-14_14.shp", options = c("ENCODING=CP932")) %>%
filter(str_starts(P34_004, "横浜市")) # 横浜市のデータのみ残す
# ggplot2 パッケージによる地図の出力
ggplot() +
# 横浜市の行政区(ポリゴン)の出力
geom_sf(data = yokohama_basemap) +
# 横浜市の市役所・区役所(ポイント)の出力
geom_sf(data = yokohama_gov, colour = "red",
size = 1.5) +
# 横浜市の市役所・区役所の名称のラベルの出力
geom_sf_text(data = yokohama_gov,
aes(label = P34_003), size = 3) +
theme_minimal()