塗り分け地図(コロプレスマップ)の作成

公開

2026年6月8日

更新日

2026年6月10日

塗り分け地図(コロプレスマップ)

コロプレスマップ(Choropleth Map)は、統計の数値によって色を塗り分けた地図のことです。 階級区分図と呼ばれることもあります。

library(tidyverse)
library(readxl)
library(sf)
library(tmap)

佐賀県の市町別塗り分け地図

佐賀県の市町村別塗り分け地図をつくってみましょう。

地図データは、佐賀県オープンデータカタログサイトにある、ポリゴン(市町村別)のGeoJSONファイルを使います。 リンクから佐賀県オープンデータカタログサイトにアクセスして、[⬇️ダウンロード]をクリックしてください。

ノートダウンロードファイル名について

GeoJSONファイルがダウンロードされたと思いますが、ダウンロードされたファイル名が非常に長くなっているかもしれません。 この場合は、ファイル名の最後の部分にある「410004saga」だけを残して、ファイル名を「410004saga.geojson」に修正しておいてください。

ダウンロードした「410004saga.geojson」を、ワーキングディレクトリのdataフォルダに移動してください。 read_sf関数を使って、GeoJSONファイルをRに読み込みます。

saga_map <- read_sf("data/410004saga.geojson")

統計データは、佐賀県オープンデータカタログサイトにある、男女別人口総数及ひ世帯総数(市町村別)を使います。

このExcelファイルは、先ほどダウンロードしたGeoJSONファイルと組み合わせて使うことが想定されていますので、これを例として説明します。

ダウンロードした「410004saga.xlsx」を、ワーキングディレクトリのdataフォルダに移動してください。 readxl::read_excel関数を使って読み込みます。

saga_dat <- read_excel("data/410004saga.xlsx")

この読み込んだ統計データには、市町別の人口データがありますので、これを使って地図を塗り分けましょう。

そこでまず、地図データと統計データを「結合」する必要があります。 地図データの中身を見ると、このようなデータが格納されています。

View(saga_map)
KEN_NAME GST_NAME CSS_NAME KEY_CODE
佐賀県 鹿島市 NA 412074
佐賀県 唐津市 NA 412023
佐賀県 神埼市 NA 412104
佐賀県 杵島郡 江北町 414247
佐賀県 多久市 NA 412040

そして統計データの中身をみると、以下のようなデータが格納されています。

View(saga_dat)
KEY_CODE 人口総数 市区町村  男  女 世帯総数
412015 236372 佐賀市 111453 124919 93306
412023 122785 唐津市 57547 65238 43872
412031 72902 鳥栖市 34799 38103 27630
412040 19749 多久市 9146 10603 6847
412058 55238 伊万里市 26395 28843 19698

両方のデータに共通するデータ列があることに気付いたと思います。 「KEY_CODE」という列に市町村コードが格納されていますが、このデータが2つのデータに共通して存在します。 そして、この市町村コードというのは全国の市町村にユニークな(一意の)番号が割り振られていますので、重複する(複数の市町村が同じコードを持つ)ことがありません。

なので、このKEY_CODEをキーにして、2つのデータを結合することにします。

2つのデータフレームを結合するには、left_join関数が便利です。 saga_mapに、KEY_CODEをキーにして、saga_datを結合するには、次のようなコードを実行します。

saga_map <- saga_map |> 
    left_join(saga_dat, by = join_by(KEY_CODE))

結果を確認してみましょう。 saga_mapのデータに、saga_datのデータが正しく結合されていることがわかります。

View(saga_map)
KEN_NAME GST_NAME CSS_NAME KEY_CODE 人口総数 市区町村  男  女 世帯総数
佐賀県 鹿島市 NA 412074 29684 鹿島市 13920 15764 10124
佐賀県 唐津市 NA 412023 122785 唐津市 57547 65238 43872
佐賀県 神埼市 NA 412104 31842 神埼市 15172 16670 10913
佐賀県 杵島郡 江北町 414247 9583 江北町 4497 5086 3225
佐賀県 多久市 NA 412040 19749 多久市 9146 10603 6847

塗り分け地図を描くのは難しくありません。 tm_polygons関数のfill引数に、塗り分けに利用したいデータ列名を指定するだけです。

tm_shape(saga_map) + tm_polygons(fill = "人口総数") +
    tm_crs(6670) + tm_compass() + tm_scalebar() +
    tm_layout(text.fontfamily = "YuGo-Medium")

日本全国の市区町村別塗り分け地図

次に、日本全国の市区町村別塗り分け地図を作ってみましょう。 市区町村の数が一気に増えますが、やることは佐賀県版の塗り分け地図と同じです。

地図データは、日本 市区町村 コロプレス地図(塗り分け地図) | 歴史的行政区域データセットβ版を使います。 リンクから、データセットの基準年月日が2023-01-01、低解像度のファイルをダウンロードしてください(リンクを右クリックして「名前を付けて保存」するといいと思います)。

ダウンロードした「jp_city.c.topojson」をデータフォルダに格納してください1

jpn_map <- read_sf("data/jp_city.c.topojson") |> st_set_crs(6668)

属性データを見てみると、N03_007というデータ列に、自治体コードが収録されていることが確認できます。

glimpse(jpn_map)
Rows: 1,909
Columns: 10
$ id         <chr> "gci:01101A1972", "gci:01102A1972", "gci:01103A1972", "gci:…
$ OBJECTID   <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, NA, NA, NA, NA, NA, NA, 802,…
$ N03_001    <chr> "北海道", "北海道", "北海道", "北海道", "北海道", "北海道", "北海道", "北海道", "北海…
$ N03_002    <chr> "石狩振興局", "石狩振興局", "石狩振興局", "石狩振興局", "石狩振興局", "石狩振興局", "石狩振興…
$ N03_003    <chr> "札幌市", "札幌市", "札幌市", "札幌市", "札幌市", "札幌市", "札幌市", "札幌市", "札幌…
$ N03_004    <chr> "中央区", "北区", "東区", "白石区", "豊平区", "南区", "西区", "厚別区", "手稲区", …
$ N03_007    <chr> "01101", "01102", "01103", "01104", "01105", "01106", "0110…
$ Shape_Leng <dbl> 0.5516441, 0.5794416, 0.4014587, 0.3107632, 0.4389366, 1.64…
$ Shape_Area <dbl> 0.005127706, 0.007032524, 0.006300214, 0.003808508, 0.00510…
$ geometry   <MULTIPOLYGON [°]> MULTIPOLYGON (((141.3552 43..., MULTIPOLYGON (…

統計データは、令和2年国勢調査の結果を利用しましょう。 国勢調査 / 令和2年国勢調査 / 人口等基本集計 (主な内容:男女・年齢・配偶関係,世帯の構成,住居の状態,母子・父子世帯,国籍など)から、Excelファイルをダウンロードし、データフォルダに格納してください。

readxl::read_excel関数を使ってファイルを読み込みます(read_excel関数の使い方については、ファイル入出力/Excelファイルの読み込み(実践編)をご覧ください)。

「地域識別コード」「自治体コード」「人口増減率」をそれぞれ「type」「code」「pop_growth_rate」というデータ列に格納しています。

jpn_dat <- 
    read_excel(
        path = "data/b01_01.xlsx",
        range = "A16:M4101",
        col_names = c("type", "code", "pop_growth_rate"),
        col_types = c("text", rep("skip", 4), "text", rep("skip", 6), "numeric"),
        na = c("", "-")
    ) |> 
    filter(type %in% c("0", "2", "3"))

読み込んだデータのうち、filter関数を使って、市区町村のデータを取り出しています。 地域識別コードの意味は、以下の表のとおりです。 ここでは地域識別コードが0、2、3のいずれかであるデータ列を抽出しています。

地域識別コード
(出所)令和2年国勢調査 調査結果の利用案内-ユーザーズガイド-
コード 地域
a 全国・都道府県
0 東京都23区及び政令指定都市の区
1 東京都特別区部及び政令指定都市
2 政令指定都市以外の市
3 町村
9 2000(平成12)年現在の市区町村

読み込んだデータを確認してみましょう2

glimpse(jpn_dat)
Rows: 1,896
Columns: 3
$ type            <chr> "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "2",…
$ code            <chr> "01101", "01102", "01103", "01104", "01105", "01106", …
$ pop_growth_rate <dbl> 4.65141, 1.40263, 1.32373, 1.07403, 3.03953, -3.83384,…

地図データと統計データをleft_join関数を使って結合します。 jpn_mapにjpn_datを結合しますが、自治体コードが前者ではN03_007という列に、後者ではcodeという列に格納されています。 その場合は、以下のようにjoin_by関数の引数を指定します。

jpn_map <- jpn_map |> 
    left_join(jpn_dat, by = join_by(N03_007 == code))

結合したファイルを確認してみましょう。

glimpse(jpn_map)
Rows: 1,909
Columns: 12
$ id              <chr> "gci:01101A1972", "gci:01102A1972", "gci:01103A1972", …
$ OBJECTID        <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, NA, NA, NA, NA, NA, NA,…
$ N03_001         <chr> "北海道", "北海道", "北海道", "北海道", "北海道", "北海道", "北海道", "北海道"…
$ N03_002         <chr> "石狩振興局", "石狩振興局", "石狩振興局", "石狩振興局", "石狩振興局", "石狩振興局", …
$ N03_003         <chr> "札幌市", "札幌市", "札幌市", "札幌市", "札幌市", "札幌市", "札幌市", "札幌市"…
$ N03_004         <chr> "中央区", "北区", "東区", "白石区", "豊平区", "南区", "西区", "厚別区", "手…
$ N03_007         <chr> "01101", "01102", "01103", "01104", "01105", "01106", …
$ Shape_Leng      <dbl> 0.5516441, 0.5794416, 0.4014587, 0.3107632, 0.4389366,…
$ Shape_Area      <dbl> 0.005127706, 0.007032524, 0.006300214, 0.003808508, 0.…
$ geometry        <MULTIPOLYGON [°]> MULTIPOLYGON (((141.3552 43..., MULTIPOLY…
$ type            <chr> "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "2",…
$ pop_growth_rate <dbl> 4.65141, 1.40263, 1.32373, 1.07403, 3.03953, -3.83384,…

塗り分け地図を書いてみましょう。 ここでは九州だけを抜き出して表示しています。

kyushu <- jpn_map |> 
    filter(N03_001 %in% c("福岡県", "佐賀県", "長崎県", "大分県", "熊本県", "宮崎県", "鹿児島県"))
tm_shape(kyushu) + 
    tm_polygons(
        fill = "pop_growth_rate",
        fill.scale = tm_scale_intervals(,
            values = "tol.bu_rd",
            midpoint = 0
        ),
        fill.legend = tm_legend("人口増減率(%)")
    ) +
    tm_crs(6670) + tm_compass() + tm_scalebar() +
    tm_layout(text.fontfamily = "YuGo-Medium")

出所)総務省統計局『令和2年国勢調査』/『日本 市区町村 コロプレス地図(塗り分け地図)| 歴史的行政区域データセットβ版』を加工して作成(CC BY 4.0

市区町村別人口増加率(2015〜2020)

脚注

  1. 「TopoJSON」は、地理空間データを扱うためのデータ形式である「GeoJSON」を拡張・軽量化したフォーマットです。↩︎

  2. 地図データの行数1,909が統計データの行数1,896よりも多いことに気づいた人もいると思います。これは、地図データには統計データがないポリゴン、具体的には北方領土と所属未定地(埋立地などで市区町村が定まっていない土地)が含まれているためです。↩︎