3 コロプレス・マップ(塗り分け地図)
3.1 概要
コロプレスマップ(塗り分け地図)を作成する方法を説明します。 佐賀県の市町村別人口密度の塗り分け地図を作成しましょう。
3.2 データの準備
「佐賀県オープンデータカタログサイト」にある「オープンデータマップ用データセット」を使用します。
- 男女別人口総数及ひ世帯総数(市町村別)
- ポリゴン(市町村別)
上記2つのファイル(410004saga.xlsx
と410004saga.geojson
)をダウンロードしてください。
ワーキングディレクトリの直下にdata
フォルダを作成し,ダウンロードしたファイルを保存してください(今後,GISデータはこのフォルダに保存することにしましょう)。
3.3 地図の描画
まず,使用するライブラリを読み込みます。ここでは,tidyverse
(地図の描画に使うggplot2
ライブラリが含まれています)に加えて,GISデータを扱うライブラリsf
を使用します。
library(tidyverse)
## ─ Attaching packages ──────────────────── tidyverse 1.3.1 ─
## ✓ ggplot2 3.3.5 ✓ purrr 0.3.4
## ✓ tibble 3.1.2 ✓ dplyr 1.0.7
## ✓ tidyr 1.1.3 ✓ stringr 1.4.0
## ✓ readr 1.4.0 ✓ forcats 0.5.1
## ─ Conflicts ───────────────────── tidyverse_conflicts() ─
## x dplyr::filter() masks stats::filter()
## x dplyr::lag() masks stats::lag()
library(sf)
## Linking to GEOS 3.8.1, GDAL 3.2.1, PROJ 7.2.1
次に,先ほどdata
フォルダに保存した410004saga.geojson
を,
sf
ライブラリのst_read
関数を使って読み込みます。
<- st_read("data/410004saga.geojson") map
## Reading layer `410004saga' from data source
## `/Users/kazukitamura/github/giswithr/data/410004saga.geojson'
## using driver `GeoJSON'
## Simple feature collection with 20 features and 4 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: 129.7368 ymin: 32.95054 xmax: 130.5424 ymax: 33.6189
## Geodetic CRS: WGS 84
読み込んだmap
データをプロットします。
ggplot() + geom_sf(data = map)
できました。簡単ですね。
3.4 地図投影変換
先ほど表示された佐賀県の地図は,横軸に経度を,縦軸に緯度をとった平面にプロットしたものでした。 これを「平面直角座標系」に変換して,表示してみましょう。
<- st_transform(map, 6670)
map2 ggplot() + geom_sf(data = map2)
微妙な違いがわかりますか?
3.5 統計データによる塗り分け
まず,利用する統計データを読み込み,中身を確認してみましょう。
Excelファイルを読み込むのに,readxl
ライブラリのread_excel
関数を使います。
library(readxl)
<- read_excel("data/410004saga.xlsx")
dat head(dat, 3)
## # A tibble: 3 x 6
## KEY_CODE 人口総数 市区町村 ` 男` ` 女` 世帯総数
## <chr> <dbl> <chr> <dbl> <dbl> <dbl>
## 1 412015 236372 佐賀市 111453 124919 93306
## 2 412023 122785 唐津市 57547 65238 43872
## 3 412031 72902 鳥栖市 34799 38103 27630
ここで,先ほど地図を描くのに使ったデータの中身もみてみましょう。
head(map2, 3)
## Simple feature collection with 3 features and 4 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: -117268.6 ymin: -1173.744 xmax: -54075.69 ymax: 69215.3
## Projected CRS: JGD2011 / Japan Plane Rectangular CS II
## KEN_NAME GST_NAME CSS_NAME KEY_CODE geometry
## 1 佐賀県 鹿島市 <NA> 412074 MULTIPOLYGON (((-82226.11 3...
## 2 佐賀県 唐津市 <NA> 412023 MULTIPOLYGON (((-106350 451...
## 3 佐賀県 神埼市 <NA> 412104 MULTIPOLYGON (((-60455.97 2...
両方のデータにKEY_CODE
という同じデータがあるのがわかります。
これをキーにして,2つのデータを結合します。
<- left_join(map2, dat) dat2
## Joining, by = "KEY_CODE"
head(dat2)
## Simple feature collection with 6 features and 9 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: -117268.6 ymin: -1173.744 xmax: -54075.69 ymax: 69215.3
## Projected CRS: JGD2011 / Japan Plane Rectangular CS II
## KEN_NAME GST_NAME CSS_NAME KEY_CODE 人口総数 市区町村 男 女 世帯総数
## 1 佐賀県 鹿島市 <NA> 412074 29684 鹿島市 13920 15764 10124
## 2 佐賀県 唐津市 <NA> 412023 122785 唐津市 57547 65238 43872
## 3 佐賀県 神埼市 <NA> 412104 31842 神埼市 15172 16670 10913
## 4 佐賀県 杵島郡 江北町 414247 9583 江北町 4497 5086 3225
## 5 佐賀県 多久市 <NA> 412040 19749 多久市 9146 10603 6847
## 6 佐賀県 東松浦郡 玄海町 413879 5902 玄海町 3035 2867 1918
## geometry
## 1 MULTIPOLYGON (((-82226.11 3...
## 2 MULTIPOLYGON (((-106350 451...
## 3 MULTIPOLYGON (((-60455.97 2...
## 4 MULTIPOLYGON (((-78005.98 2...
## 5 MULTIPOLYGON (((-76464.8 27...
## 6 MULTIPOLYGON (((-106304.2 5...
このように,対応する2つのデータを結合するときには,dplyr
ライブラリのleft_join
関数が便利です。この関数が2つのデータに共通の列名を自動的に見つけて,そのデータに基づいて2つのデータを結合してくれます。これで,地図データに人口や世帯数のデータを結びつけることができました。
この章の目的は,人口密度のコロプレスマップを作ることですので,市町村の面積データが必要です。先ほどと同様に,別のところから面積データを持ってきでjoinしてもいいのですが,ここでは地図データから面積を計算してみましょう。sf
ライブラリのst_area
関数を使います。
$area <- st_area(dat2)
dat2$area <- units::set_units(dat2$area, km^2)
dat2$area <- units::drop_units(dat2$area)
dat2$density <- dat2$人口総数 / dat2$area
dat2head(dat2)
## Simple feature collection with 6 features and 11 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: -117268.6 ymin: -1173.744 xmax: -54075.69 ymax: 69215.3
## Projected CRS: JGD2011 / Japan Plane Rectangular CS II
## KEN_NAME GST_NAME CSS_NAME KEY_CODE 人口総数 市区町村 男 女 世帯総数
## 1 佐賀県 鹿島市 <NA> 412074 29684 鹿島市 13920 15764 10124
## 2 佐賀県 唐津市 <NA> 412023 122785 唐津市 57547 65238 43872
## 3 佐賀県 神埼市 <NA> 412104 31842 神埼市 15172 16670 10913
## 4 佐賀県 杵島郡 江北町 414247 9583 江北町 4497 5086 3225
## 5 佐賀県 多久市 <NA> 412040 19749 多久市 9146 10603 6847
## 6 佐賀県 東松浦郡 玄海町 413879 5902 玄海町 3035 2867 1918
## geometry area density
## 1 MULTIPOLYGON (((-82226.11 3... 111.11309 267.1512
## 2 MULTIPOLYGON (((-106350 451... 487.16068 252.0421
## 3 MULTIPOLYGON (((-60455.97 2... 124.00616 256.7776
## 4 MULTIPOLYGON (((-78005.98 2... 24.83140 385.9226
## 5 MULTIPOLYGON (((-76464.8 27... 96.67014 204.2927
## 6 MULTIPOLYGON (((-106304.2 5... 35.90699 164.3691
平面直角座標系の距離がm単位になっていますので,st_area
で計算した面積はm2単位になっています。
そこで,unitsライブラリの
set_units関数で,km2単位に変換しています。
さらに,人口密度を計算するときに単位が邪魔なので,drop_units
関数で単位を落としています。
さて,塗り分け地図を描くには,geom_sf
の中で,densityでfillしろと指示するだけです。
2行目は塗り潰しの色(カラーパレット)を指定しています。
ggplot() + geom_sf(mapping = aes(fill = density), data = dat2) +
::scale_fill_continuous_sequential("YlGn") colorspace