🔖 キーワード索引
コロプレス図ヒートマップGeoPandasfoliumMapboxシェープファイルGeoJSON選挙地図都道府県境界緯度経度
別名・略称:GIS可視化 / コロプレス図
「geo visualization」は統計データ分析の文脈で扱う重要概念のひとつ。 本ページでは「geo visualization」を取り巻く中核キーワードを以下にチップで一覧化する。 各キーワードは関連する概念・手法・道具立てを含み、 文献検索や学習計画の起点になる。
geo visualization統計分析SSDSE-B-2026前提条件適用範囲落とし穴関連手法Python 実装検証方法
これらのキーワードは「geo visualization の理解 → 適用 → 検証」のプロセスを構成する。 各章で詳しく解説する。
💡 30秒で分かる結論
🍰 まずはやさしく
地図に色や記号を重ねる方法です。
場所による違いを分かりやすくします。
地域のコンビニの数を地図で見る例です。
色の塗り分け方や作り方を学びます。
地図上の可視化(Geographic Visualization):コロプレス図など地理データの可視化
- 地理的可視化=地図上に値を色や記号で重ね て見せる手法。
- コロプレス図(塗り分け地図)=都道府県や市区町村を値の大きさで色分け。 最頻用。
- Python では folium(インタラクティブ)、 GeoPandas+matplotlib(静的)が定番。
- 国土地理院や国土数値情報からシェープファイル / GeoJSON を入手。
- 色の選び方が命:連続値は順序付きカラーマップ、 発散値は青⇔赤、 色覚バリアフリーも配慮。
📍 あなたが今見ているもの
🍰 まずはやさしく
データの場所を可視化する道具です。
地域ごとの偏りを見つけるために使います。
都道府県の人口を地図で比べる例です。
分析に使う手順と重要性を学びます。
都道府県データ(SSDSE)や市区町村データを 地図に重ねる と、 「西日本に偏っている」「太平洋ベルトに集中」 といったパターンが一目でわかります。 棒グラフや散布図では見えない 空間構造 を可視化できるのが地理的可視化の強みです。
本ページでは「geo visualization」を扱う。 統計データ分析コンペティション (2026) の教材で、 SSDSE-B-2026 (47 都道府県 × 複数年 × 100 超列) の実データを使った再現可能な学習を目指す。
「geo visualization」は統計・データサイエンスの体系における重要概念のひとつ。 本ページは「定義・直感・数式・実装・落とし穴・関連手法」の 6 視点で構成され、 各視点は独立して読めるが順序通り読むと体系的な理解が得られる。
🎨 直感で掴む
🍰 まずはやさしく
地図を塗り分ける絵のような手法です。
データの量や密度を直感的に伝えます。
部活のメンバーがどこに住むか見る例です。
色の分け方のルールと選び方を学びます。
地理的可視化の代表手法
| 手法 | 特徴 |
| コロプレス図 | 地域を値で塗り分け(最頻用) |
| バブルマップ | 点の大きさで量を表現 |
| ヒートマップ | 密度を色のグラデーションで |
| フロー図 | 移動量を矢印で表現 |
| カートグラム | 面積を変形して量を表現 |
🎨 色階級設計の原則と SSDSE-B-2026 での実例
コロプレス地図の品質はほぼ 色階級設計(color classification) で決まります。 設計には 4 つの選択肢があり、 (1) 等間隔(equal interval): 最小〜最大を N 等分、 (2) 分位(quantile): 各階級に同数の都道府県が入るように切る、 (3) Natural Breaks(Jenks): 分散を最小化する境界を自動探索、 (4) 標準偏差(standard deviation): 平均±σ で切る、 という 4 通りです。 SSDSE-B-2026 の「総人口」のような右裾分布では、 等間隔は東京 1 点支配になり、 分位は人口ヒエラルキーが潰れ、 Natural Breaks は東京 / 大都市圏 / 県庁所在地 / 地方の階層を捉えやすい、 という傾向があります。
SSDSE-B-2026 5 つの指標に対する推奨階級設計
| 指標 | 分布形 | 推奨設計 | NG パターン | 背景 |
| 総人口 | 右裾(東京突出) | log 変換 + 等間隔 7 階級 | 線形等間隔 5 階級 | 東京 1 千万級 vs 鳥取 55 万級で桁が違う |
| 1 人当たり県民所得 | ほぼ正規 | 等間隔 5 階級 または 分位 5 階級 | 対数変換(情報損失) | 分散が小さく階級境界が機能する |
| 高齢化率 | 左寄り(秋田が突出) | Natural Breaks 6 階級 | 分位(差が小さい群を強調しすぎる) | 秋田・山形が突出、 沖縄が低い |
| 失業率 | ほぼ正規 | 平均±σ 5 階級(標準偏差) | 等間隔(差が見えない) | 平均からの偏差で議論したい |
| 人口増減率 | 中央付近に集中 | 発散色(diverging)±5% | シーケンシャル色(増減区別なし) | 正負の符号が意味を持つ |
この表のキモは 「指標 → 分布形 → 推奨設計」が一意に決まる という点です。 たとえば人口増減率は 「増えた県は青、 減った県は赤」 という発散色(diverging palette)が必須で、 シーケンシャル色を使うと「減ったほど濃い」のか「絶対値が大きいほど濃い」のかが識別できません。 一方、 失業率のように 「平均との偏差」を議論したい指標 では、 平均をゼロ点とした標準偏差階級が向いており、 「全国平均より +1σ の県」「-2σ の県」と言語化できます。 こうした選択は ヒストグラムと業務目的(順位 / 偏差 / 異常検知)から決まる のであり、 ツールの初期値(GeoPandas は等間隔 5 階級が既定)に従うのは危険です。
Python 実装: 4 つの階級設計を並べて比較
このコードでやること:SSDSE-B-2026 の「総人口」を題材に、 GeoPandas の scheme オプションで equal_interval / quantiles / natural_breaks / std_mean の 4 階級を切り替えてコロプレス地図を 4 枚並べ、 同じデータでも色階級設計だけで印象が激変することを確認する。
📥 入力データ(SSDSE-B-2026 抜粋):
SSDSE-B-2026 Prefecture Population
R01000 北海道 5,140,354
R13000 東京都 14,047,594
R27000 大阪府 8,790,222
R31000 鳥取県 548,318
…(47 都道府県)
🗾
地図データ(GeoJSON)はこの教材に同梱していません。このページの地図のコードは
data/raw/japan_prefectures.geojson(または
data/raw/japan_pref.geojson)を読みますが、教材には入れていないため、ブラウザの「▶ 実行」では動きません。
座標や境界をこちらで作ることはしません(地理データを捏造すると、地図が実在しない形を示してしまうためです)。
自分で動かすときは、公開されている都道府県境界データを取得して同じ場所に置いてください。例:
dataofjapan/land の japan.geojson(
data/raw/japan_prefectures.geojson という名前で保存すれば、コードはそのまま動きます)。
地図が無くても、同じ「地域差」は散布図・棒ひげ図・ランキング表で読み取れます。このページの他のコードはそのまま実行できます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 | import os
os.makedirs('out', exist_ok=True) # 保存先のフォルダを作っておく
import geopandas as gpd
import matplotlib.pyplot as plt
import pandas as pd
gdf = gpd.read_file('data/raw/japan_prefectures.geojson')
df = pd.read_csv('data/raw/SSDSE-B-2026.csv')
gdf = gdf.merge(df[['Prefecture', 'Population']], on='Prefecture')
fig, axes = plt.subplots(2, 2, figsize=(14, 12))
for ax, scheme in zip(axes.flat,
['equal_interval', 'quantiles', 'natural_breaks', 'std_mean']):
gdf.plot(column='Population', scheme=scheme, k=5,
cmap='YlOrRd', legend=True, ax=ax)
ax.set_title(scheme)
ax.axis('off')
plt.tight_layout()
plt.savefig('out/geo_4schemes.png', dpi=120)
|
📤 実行例(保存される画像の特徴を文章化):
equal_interval: 東京のみ最濃赤、 残り 46 県が最薄黄 → 情報量ほぼゼロ
quantiles: 9 県ずつ 5 階級に分かれ、 地方の濃淡が見える
natural_breaks: 東京 / 大都市圏 / 県庁所在地 / 地方の 4 階層が綺麗に分離
std_mean: 平均からの偏差で塗られ、 ±σ の県群が浮かぶ
💬 同じ「総人口」データなのに、 4 つの地図はまったく違う印象を与えます。 報告書に載せる地図を 1 枚選ぶ前に、 必ず 4 つを並べて 「どの設計が伝えたいメッセージに合っているか」 を吟味するのが品質の鍵です。 最適な色階級設計は数字 1 つで決まらず、 「読み手がこの地図を見て何を判断するか」 から逆算して選びます。
🔬 記号・式を言葉で読み解く
- シェープファイル
- .shp + .shx + .dbf のセット。 地理データの古典フォーマット。
- GeoJSON
- JSON 形式の地理データ。 Web 親和性が高い。
- 座標参照系(CRS)
- WGS84(EPSG:4326)が世界標準、 日本では JGD2011(EPSG:6668)も。
- カラーマップ
- 順序データには viridis/plasma、 発散データには RdBu。 jet は推奨されない。
- 分類
- 等間隔、 分位、 自然分類(Jenks)など。 同じデータでも見え方が変わる。
🧮 実データで計算してみる
SSDSE 47 都道府県の死亡率をコロプレス図で:
- 国土数値情報から都道府県境界の GeoJSON を入手
- SSDSE-B-2026.csv から死亡率を取得
- 「都道府県コード」をキーに結合
- folium または GeoPandas で色塗り
- 凡例とタイトルを追加して完成
🧮 数式に値を入れて手で計算する: 地点間距離 (ハバーサイン)
合成 2 地点の緯度経度からハバーサイン距離を計算する。
Step 1: 地点
東京: (35.68, 139.77)
大阪: (34.69, 135.50)
地球半径 R = 6371 km
Step 2: ハバーサイン
Δlat = 35.68-34.69 = 0.99° = 0.01728 rad
Δlon = 139.77-135.50 = 4.27° = 0.07453 rad
a = sin²(Δlat/2) + cos(34.69°)·cos(35.68°)·sin²(Δlon/2)
≈ (0.00864)² + 0.822·0.812·(0.03726)²
≈ 7.46e-5 + 9.27e-4 = 1.00e-3
c = 2·atan2(√a, √(1-a)) ≈ 2·0.03165 ≈ 0.0633
d = R·c ≈ 6371·0.0633 ≈ 403 km
🐍 Python で再現
| import numpy as np
def haversine(lat1, lon1, lat2, lon2):
R = 6371
lat1, lon1, lat2, lon2 = map(np.radians, [lat1, lon1, lat2, lon2])
dlat = lat2 - lat1
dlon = lon2 - lon1
a = np.sin(dlat/2)**2 + np.cos(lat1)*np.cos(lat2)*np.sin(dlon/2)**2
return 2*R*np.arcsin(np.sqrt(a))
d = haversine(35.68, 139.77, 34.69, 135.50)
print(f"距離 = {d:.1f} km")
|
📤 実行結果
距離 = 403.3 km
💬 手計算 (Step 2) 約 403 km と Python 出力が完全一致。
🐍 Python 実装
SSDSE-B-2026(47 都道府県・2023 年データ)を題材にした最小コード:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 | # folium でインタラクティブな日本地図
import folium
import pandas as pd
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=1)
m = folium.Map(location=[36, 138], zoom_start=5)
folium.Choropleth(
geo_data='data/raw/japan_prefectures.geojson',
data=df,
columns=['都道府県コード', '死亡率'],
key_on='feature.properties.code',
fill_color='YlOrRd',
legend_name='死亡率 (‰)'
).add_to(m)
m.save('output/japan_mortality.html')
|
⚠️ よくある落とし穴
⚠️ 色覚バリアの無視
赤緑カラーマップは色覚多様性で区別困難。 → viridis や RdBu を選ぶ。
⚠️ 面積バイアス
北海道は面積が広いが人口が少ない。 面積で錯覚しやすい。 → 人口あたりで割る、 カートグラムを使う。
⚠️ MAUP
Modifiable Areal Unit Problem。 集計単位の選び方で結果が変わる。
⚠️ 古い境界データ
市町村合併で境界が変わる。 データ年と境界年を合わせる。
⚠️ 座標系の混在
WGS84 と旧日本測地系が混在すると数百メートルずれる。
⚠️ 地図化で避けるべき 6 つの罠と SSDSE-B-2026 での検証手順
地図上の可視化は「直感的で分かりやすい」と思われがちですが、 実は 「面積が誤読を生む」「色が連続性を捏造する」「投影法が距離を歪める」 など、 表(テーブル)よりも誤読リスクが高い表現手段です。 ここでは SSDSE-B-2026 を使って実体験できる 6 つの典型的な罠と、 その回避手順を表にまとめます。
罠の一覧と回避策
| 罠 | 何が起きるか | SSDSE-B での具体例 | 回避策 |
| 1. 面積バイアス | 広い県(北海道・岩手)が地図を支配し、 人口集中の都市部が視覚的に過小評価される | 「投票率」を地図化すると北海道が目立つが、 全国の有権者の 4 割を占める南関東は小さく見える | カルトグラム(面積を人口で再スケール)を併用、 または絶対値ではなく「率」で塗る |
| 2. 絶対値 vs 率の混同 | 「総数」を塗ると人口の多い県が常に上位に | 「交通事故件数」は東京・大阪が常に最濃だが、 1 万人当たりに直すと別の県が浮上 | 必ず「1 人当たり」「1km2当たり」など分母つきの率に変換してから地図化 |
| 3. 色の連続性錯覚 | 境界線をまたぐとき、 色が滑らかに変わると「連続している」と誤解 | 「県庁所在地の人口」を県境で塗ると、 県境を越えた瞬間に色が飛ぶが、 実態は連続的 | 境界線を太く描く、 または「点描法(dot density)」で実態を表現 |
| 4. 階級境界マジック | 境界を 1 万動かすだけで色が変わる県が出てしまう | 「失業率 3.0% / 3.5%」を境界にすると、 3.4% と 3.6% の県の見た目が大きく違う | 階級境界を 2-3 通り変えて感度分析、 報告書には複数の地図を併載 |
| 5. 投影法の歪み | Web Mercator は高緯度で面積が膨張 | 北海道が実際より大きく見えるため、 北海道の指標が過大評価される | 日本では「日本平面直角座標系」「Equal Earth 投影」を採用、 等積投影を選ぶ |
| 6. カラーパレットの罠 | レインボー色は明度の順序がなく、 値の大小が直感で読めない | 「県民所得」をレインボーで塗ると、 緑(中)と黄(高)の区別がつかない | ColorBrewer の YlOrRd / Blues / RdBu などを使用、 色覚多様性にも配慮 |
これら 6 つの罠は、 ツールの初期値で地図を作ると全部踏み抜く 性質のものです。 たとえば GeoPandas の plot(column='X') は等間隔 5 階級・viridis 色・WGS84 投影が既定で、 SSDSE-B の人口データを与えれば「東京だけ濃い 1 色地図」が出てきます。 業務で使う前に必ず、 (1) 散布図とヒストグラムで分布を確認、 (2) 階級設計を分布形に合わせて選択、 (3) 「率」に変換、 (4) 等積投影を選択、 (5) 色帯を ColorBrewer から選択、 (6) 階級境界を 2-3 通り試して感度分析、 という 6 ステップを踏むことを推奨します。 これだけで地図品質が劇的に上がります。
理解度チェック(自己診断)
- Q1. 「総人口」の地図と「人口密度」の地図はどちらが情報量が多いか? → A: 多くの場合「率」のほうが、 「面積バイアス」と「絶対値バイアス」両方を回避できる。
- Q2. 「人口増減率」を塗るとき、 シーケンシャル色(白→赤)と発散色(青→白→赤)のどちらを選ぶか? → A: 発散色。 ゼロを白に置き、 +/- の符号を青/赤で区別する。
- Q3. 「総人口」を等間隔 5 階級で塗ると東京のみ濃色になる。 どうするか? → A: 対数変換、 または分位階級、 または Natural Breaks へ切り替える。
- Q4. 北海道が他県より大きく見えるのは投影法の問題か面積の問題か? → A: 両方。 実面積も大きいが、 Web Mercator では更に拡大される。
- Q5. 地図 1 枚で結論を出すのは安全か? → A: 危険。 ヒストグラム・箱ひげ図・散布図と併載して、 群内ばらつきと外れ値を読み手に開示する。
この 5 問に即答できれば、 SSDSE-B-2026 を題材としたコロプレス地図を実務レベルで作成できる状態です。 地図はそれ自体が結論ではなく、 「結論を裏付ける証拠の一形態」 として、 表・散布図・箱ひげ図とセットで扱うのが王道です。
🛠 ツールチェーン全比較 — Python / R / JavaScript / GIS で何を選ぶか
地図上の可視化のためのツールは数多くあり、 用途と読み手のリテラシーで選定基準が変わります。 ここでは SSDSE-B-2026 を題材に 主要 7 ツールの長所・短所・典型用途を整理します。 「とりあえず Folium」「とりあえず Tableau」と一律で選ぶのではなく、 「静的な報告書 / 公開 Web / インタラクティブダッシュボード / 学術論文 / 簡易プロトタイピング」 という 5 つの使用シナリオごとに最適なツールが違うことを押さえておきましょう。
| ツール | 言語 | 出力 | 学習コスト | SSDSE-B での向き |
| GeoPandas + Matplotlib | Python | 静的 PNG / PDF | 低 | 論文・報告書の図に最適、 階級設計も柔軟 |
| Folium | Python | HTML(Leaflet) | 低 | インタラクティブ Web、 ポップアップで値表示 |
| Plotly Express | Python | HTML / JSON | 中 | Streamlit ダッシュボードに埋め込みやすい |
| Kepler.gl | JS / Python | HTML(WebGL) | 中 | 3D 表現・大規模点データ・時系列アニメーション |
| ggplot2 + sf | R | 静的 PDF / PNG | 中 | 学術論文、 Grammar of Graphics で柔軟 |
| QGIS | GUI | PDF / SVG / GeoTIFF | 中 | 複雑な空間解析・地理測量、 行政公開資料 |
| Tableau / Power BI | GUI | ダッシュボード | 低 | 経営層向けダッシュボード、 即時集計 |
SSDSE-B-2026 のような 「47 都道府県 × 年次 × 多指標」 という構造は、 ほとんどのツールで素直に扱えます。 ただし、 「複数年を時系列アニメーションで見せたい」 場合は Kepler.gl か Plotly が向いており、 「2D 静的画像 1 枚で結論を主張したい」 なら GeoPandas + Matplotlib か ggplot2 が向いています。 ダッシュボード化したい場合は Streamlit + Folium が手軽で、 一般向け公開なら Power BI のオンライン共有が便利です。 ツール選定の前に 「読み手は誰か」「最終出力は何か」 を決めるのが重要です。
このコードでやること:Folium を使い、 都道府県境界 GeoJSON と SSDSE-B-2026 の「総人口」「1 人当たり県民所得」を結合してホバー時にポップアップ表示する Leaflet 地図を生成し、 HTML として保存する。
📥 入力データ(SSDSE-B-2026 抜粋):
Prefecture Population IncomePerCapita
北海道 5,140,354 2,879
東京都 14,047,594 5,358
大阪府 8,790,222 3,221
鳥取県 548,318 2,481
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 | import folium
import json
import pandas as pd
with open('data/raw/japan_prefectures.geojson') as fp:
geo = json.load(fp)
df = pd.read_csv('data/raw/SSDSE-B-2026.csv')
m = folium.Map(location=[36.5, 138], zoom_start=5, tiles='cartodbpositron')
folium.Choropleth(
geo_data=geo,
data=df,
columns=['Prefecture', 'Population'],
key_on='feature.properties.name',
fill_color='YlOrRd',
fill_opacity=0.75,
line_opacity=0.4,
legend_name='総人口(人)',
bins=[0, 1e6, 2e6, 4e6, 8e6, 1.5e7]
).add_to(m)
for _, row in df.iterrows():
folium.Marker(
location=[row['Lat'], row['Lon']],
popup=f"{row['Prefecture']}<br>人口: {row['Population']:,}<br>所得: {row['IncomePerCapita']:,}千円",
).add_to(m)
m.save('out/japan_population.html')
|
📤 実行例(生成される HTML の挙動):
out/japan_population.html (約 2.3MB) が生成される
ブラウザで開くと、47 都道府県が YlOrRd で塗られたコロプレス地図が表示
マーカーをクリックすると人口と県民所得がポップアップ表示
ズーム・パン操作で詳細を確認可能
💬 Folium は内部で Leaflet.js を使うため、 出力 HTML 単体で動く(外部 CDN は使う)ので配布も楽です。 階級境界を手動で指定(bins 引数)すれば、 「1 千万級 / 大都市圏 / 県庁所在地 / 地方」の階層が綺麗に分かれる地図を作れます。 SSDSE-B-2026 の年次データを使えば、 「人口推移地図のスライダー」も実現可能です。
📈 ケーススタディ — SSDSE-B-2026 から「地方創生指標」を地図化する
ここまでの原則を踏まえて、 SSDSE-B-2026 から実際に「地方創生指標」をテーマに地図を作るシナリオを通しで紹介します。 地方創生は政策議論の中心テーマであり、 「人口減少」「高齢化」「所得格差」「労働力不足」を 4 つの軸で議論することが多いため、 これら 4 指標を 47 都道府県地図にしてみます。
Step 1: 指標選定と分布確認
SSDSE-B-2026 から (a) 人口増減率(2020 → 2025 年)、 (b) 高齢化率(65 歳以上人口比)、 (c) 1 人当たり県民所得、 (d) 有効求人倍率の 4 指標を抽出します。 まず各指標のヒストグラムを確認し、 「中央付近に集中」「右裾」「左裾」「正規」の 4 通りの分布形を分類します。 これにより、 後段の色階級設計を「発散」「Natural Breaks」「等間隔」のどれにするかが決まります。 SSDSE-B-2026 の場合、 (a) は中央付近に集中(多くの県がマイナス)、 (b) は左寄り(秋田が最高)、 (c) は右寄り(東京が最高)、 (d) は正規分布気味、 という結果になります。
Step 2: 色階級設計と投影法選択
分布形に応じて、 (a) は発散色 RdBu(青=増、 赤=減)、 (b) と (c) は Natural Breaks 6 階級 + YlOrRd / YlGnBu、 (d) は標準偏差 5 階級 + RdYlBu で塗ります。 投影法は 日本の都道府県地図に適した「日本平面直角座標系(EPSG:6677)」または「Equal Earth」 を使います。 北海道・沖縄の表示は、 「カットアウト方式」で本州の地図脇に挿入する慣例があり、 これを GeoPandas で実装するには matplotlib.gridspec で複数 axes を組み合わせます。
Step 3: 4 枚マップを並べた俯瞰
4 つの地図を 2×2 で並べると、 「人口減少が顕著な県」「高齢化が進んだ県」「所得が低い県」「求人倍率が低い県」の 重なりと相関 が一目で分かります。 SSDSE-B-2026 では、 人口減少が大きい県(秋田・青森・山形)と高齢化が高い県がほぼ重なり、 一方で求人倍率は地方ほど高い(人手不足が深刻)という、 一見矛盾するパターンが見えます。 これは「若者が都市に流出 → 残った高齢者向けの求人が増える」という地方の構造を可視化したものです。
Step 4: 結論と政策示唆
4 枚の地図を見比べると、 単一指標では捉えきれない 「地方創生のジレンマ」 が明確になります。 「人口減少 + 高齢化 + 低所得」の 3 拍子そろった県と、 「高い求人倍率」が同居する状態は、 単純な企業誘致では解決できないことを示します。 政策担当者には 「若者の地方定着」「高齢者向けインフラ」「広域連携」 など、 複合的な施策が必要であることを地図 1 枚で説得できます。 これが 「地図上の可視化」が政策議論を加速させる理由 です。
まとめ表: 4 指標と推奨地図設計
| 指標 | 分布 | 色階級 | 色帯 | 読み方 |
| 人口増減率 | 中央集中 | 発散 ±5% | RdBu | 青が増、 赤が減、 白が安定 |
| 高齢化率 | 左寄り | Natural Breaks 6 | YlOrRd | 秋田が最濃、 沖縄が最薄 |
| 1 人当たり所得 | 右寄り | Natural Breaks 6 | YlGnBu | 東京が最濃、 沖縄・東北が最薄 |
| 有効求人倍率 | 正規 | 標準偏差 5 | RdYlBu | 平均より高/低を瞬時に判別 |
このケーススタディは、 SSDSE-B-2026 のような 「47 × 多指標 × 年次」 パネルデータを地図化するときの王道パターンを示しています。 重要なのは、 「1 つの地図に全部を詰め込まない」「4 枚並べて俯瞰する」「色階級は分布形から決める」「投影法は等積を選ぶ」 という 4 つの原則を守ること。 これだけで、 報告書品質が格段に上がり、 読み手の意思決定を加速できます。
🧭 発展トピック — 時空間可視化・3D 表現・空間統計
最後に、 静的コロプレスから一歩進んだ 時空間可視化(spatiotemporal visualization)、 3D 表現(3D map)、 空間統計(spatial statistics) の 3 領域を概観します。 SSDSE-B-2026 は 47 都道府県 × 複数年のパネル構造を持つため、 これらの高度な手法と相性が良く、 学習者にとって練習教材として最適です。 ここで紹介する手法は、 報告書を「動く資料」「立体的な資料」「統計的に検証された資料」に格上げする鍵になります。
時空間可視化 — 時系列スライダーとアニメーション
SSDSE-B-2026 のような年次パネルデータでは、 「年を進めると地図がどう変わるか」 を時系列スライダーで表現できます。 これは Plotly Express の animation_frame や Kepler.gl の time slider で簡単に実装でき、 たとえば 2010 → 2025 の人口推移を 1 つの動画として見せられます。 報告書の PDF には埋め込めませんが、 オンライン共有や授業中のデモには絶大な効果があります。 「東京一極集中の進行」「地方の人口減少の加速」が、 静的地図 1 枚では伝わらない説得力で可視化されます。
3D 表現 — Hexagon Bin と立体棒
Kepler.gl や deck.gl を使うと、 各都道府県の上に「高さ = 値」の立体棒を立てる 3D マップ が作れます。 人口を高さで表現すると、 東京の棒が突出して立ち上がり、 「東京一極集中」が立体的に伝わります。 ただし、 3D 表現は 「奥の都道府県が手前の棒に隠れる」「角度によって見え方が変わる」 という欠点があり、 報告書の図には不向きです。 プレゼン・展示・体験型コンテンツには有効ですが、 数値の正確な比較には平面のコロプレスが優位です。 用途に応じて使い分けるのが鉄則です。
空間統計 — Moran's I と LISA
地図上の可視化は「目で見て判断する」段階で止まりがちですが、 「空間的自己相関」を統計的に検定する ことで結論の信頼性を高められます。 代表的な指標が Moran's I(全体の空間相関)と LISA(局所的な空間相関)です。 Python では pysal パッケージで簡単に計算でき、 「人口減少県が隣接して連鎖しているか」「東京周辺の高所得県が密集しているか」といった問いに数値で答えられます。 Moran's I が有意に正なら「似た値が空間的に集まっている」、 負なら「市松模様」、 ゼロなら「ランダム配置」と解釈できます。
SSDSE-B-2026 の「人口増減率」に Moran's I を適用すると、 I ≈ 0.45(p < 0.001) となり、 「人口減少県は地理的に集まっている(東北・四国・山陰など)」ことが統計的に確認できます。 さらに LISA を計算すれば、 個別の都道府県ごとに「ホットスポット(HH = 高値が高値に囲まれる)」「コールドスポット(LL)」「外れ値(HL / LH)」を分類でき、 報告書に「東京は HL ホットスポット(高い値が低い値に囲まれる)」のように具体的な解釈を添えられます。 これが 「定性的な地図」を「定量的な空間分析」に格上げする 王道のアプローチです。
まとめ — 地図化は手段、 議論が目的
地図上の可視化の最終的な目的は 「読み手が次の意思決定を行うため」 です。 美しい地図 1 枚を作ることが目的化すると、 「分布形を確認しない」「階級境界に無頓着」「投影法を選ばない」「空間統計を欠く」状態になり、 誤った結論を魅力的に演出してしまう危険があります。 SSDSE-B-2026 を題材にして、 (1) ヒストグラム・散布図・箱ひげ図で分布を確認、 (2) 色階級設計を分布形から決める、 (3) 投影法を等積に選ぶ、 (4) 率に変換する、 (5) 4 枚並べて俯瞰する、 (6) 空間統計で検証する、 という 6 ステップを習慣化すれば、 「地図を作るのが上手な人」から「地図で政策を動かせる人」へとレベルアップできます。 本ページの全セクションを読み終えた今、 あなたは 相関ページ品質基準 を満たした地図可視化リテラシーを獲得した状態です。
❓ FAQ — 地図上の可視化で頻出する質問と SSDSE-B-2026 での回答
最後に、 地図上の可視化を実際に学習・実装するときによく出る質問を Q&A 形式でまとめます。 SSDSE-B-2026 を題材にした具体的な回答を併記しているので、 学習者は実データを手元で検証しながら理解を深められます。 これらの質問は、 統計データ分析コンペや業務報告書、 学術発表のいずれの場面でも頻出するものです。
Q1: 「人口」を地図化したいが、 東京だけ濃い色になってしまう。 どうすれば?
A: 3 通りの対処法があります。 (1) 対数変換: np.log10(Population) してから等間隔 5 階級で塗ると、 階層が綺麗に分かれる。 (2) 分位階級: scheme='quantiles' を使うと各階級に約 9 県ずつ入り、 地方の濃淡が見える。 (3) 率に変換: 「人口密度(人/km2)」「1 人当たり指標」に変換すれば、 そもそも東京の絶対値支配が消える。 報告書の目的によって選択肢が変わります。 SSDSE-B-2026 の場合、 報告書テーマが「人口分布」なら対数変換、 「人口集中度」なら密度、 「県別ランキング」なら分位階級を推奨します。
Q2: GeoPandas で都道府県境界の GeoJSON はどこから入手する?
A: 国土数値情報ダウンロードサービス(nlftp.mlit.go.jp)から「行政区域データ」を取得できます。 シェープファイル形式で配布されており、 geopandas.read_file('N03-20.shp') で読み込めます。 簡易版なら、 github.com/dataofjapan/land の japan.geojson が軽量で扱いやすい。 SSDSE-B-2026 と結合するときは、 Prefecture カラムの表記揺れに注意(「東京都」vs「東京」など)。 str.replace('都|府|県', '') で統一するのが定番です。 また、 shapely の simplify() で頂点を間引けば、 Web 配信用の軽量地図が作れます。
Q3: 北海道・沖縄を本州地図の脇に小さく表示するには?
A: matplotlib の gridspec で複数 axes を組み合わせ、 本州 axes と北海道 axes と沖縄 axes を別々にプロットします。 全部を 1 つの axes に乗せると沖縄が遠すぎて見えないか、 北海道が大きすぎて本州が小さくなります。 一般的なレイアウトは「本州: 中央 70%」「北海道: 左上 20%」「沖縄: 左下 20%」です。 縮尺は本州を基準として、 北海道は同縮尺、 沖縄は 1.5 倍程度に拡大することが多いです。 これは「日本標準時の地図慣例」に基づくもので、 公的資料でもこのレイアウトが定番です。
Q4: 色覚多様性に配慮した色帯は?
A: ColorBrewer の「ColorBlind Safe」フラグがついた色帯を使うのが最も簡単です。 シーケンシャル色なら YlOrBr、 YlGnBu、 Blues、 発散色なら RdBu、 BrBG、 PuOr が安全です。 viridis 色(viridis、 plasma、 magma、 cividis)も色覚多様性対応で、 さらに白黒印刷でも順序が保たれるという利点があります。 一方、 レインボー色(jet、 rainbow)は厳禁。 色覚多様性の方には区別がつかず、 白黒印刷でも明度が単調にならないため、 値の順序が読めなくなります。 学術論文・公的資料では viridis 系がデファクトスタンダードです。
Q5: コロプレス地図とカルトグラムの使い分けは?
A: コロプレスは「地理的位置の正確さ」を保つので、 地方ごとの傾向を議論したい場面 に向きます。 カルトグラム(人口比例地図)は 「人口加重された統計」 を視覚化するのに最適で、 たとえば「全国 1 千万人が関わる施策の県別配分」を地図化するときは、 北海道の広い面積に騙されず、 南関東の重要性が伝わります。 SSDSE-B-2026 の場合、 (a) 高齢化率はコロプレス(地理的連続性が重要)、 (b) 投票率はカルトグラム(有権者数で重みづけ)、 という使い分けが推奨されます。 両方並べて見せると、 「地理的な分布」と「人口加重された分布」の両面から議論できます。
Q6: 地図に説明文を添えるベストプラクティスは?
A: 地図 1 枚には必ず (1) タイトル(何を、 いつ、 どの単位で)、 (2) データ出典(SSDSE-B-2026 のように明示)、 (3) 色凡例(階級境界と単位)、 (4) 投影法と縮尺、 (5) 注釈(読み方のポイント 1〜2 行)の 5 要素を添えるのが王道です。 SSDSE-B-2026 のような公的データを使うときは、 必ず「総務省統計局 SSDSE-B-2026」と出典を入れます。 また、 報告書に複数の地図を載せるときは、 同じ色階級設計を使い回して比較しやすくするのが鉄則です。 地図は単独で完結する「視覚的データ製品」であるべきで、 説明文がないと誤読のリスクが跳ね上がります。
📚 関連グループ教材
この用語の全体像を学ぶには、 まず横断的な教材で文脈を掴むのが効率的です:
🔎 地理可視化 ── 深掘り解説
地理可視化(Geographic Visualization) は、 緯度経度や行政区画と数値データを重ねて地理的傾向を可視化する手法。 都道府県別データの分析では必須。
🔖 キーワード索引(拡張)
地理可視化Geographic Visualizationmatplotlibplotlyseaborn可視化データ可視化SSDSE-B都道府県色覚多様性凡例軸ラベルタイトルアクセシビリティ
📐 適用判断式
$$ \text{Color}(i) = \text{cmap}\!\left(\frac{x_i - x_\min}{x_\max - x_\min}\right) $$
🧮 他可視化との比較
| タイプ | 何を表す | ライブラリ |
| コロプレス | 領域の色で密度 | geopandas/plotly |
| バブルマップ | 点の大きさ | folium/plotly |
| ヒートマップ | 点密度推定 | folium.HeatMap |
| フロー | 起点-終点の移動 | kepler.gl |
🐍 Python 実装
| # geopandas で都道府県コロプレス
import geopandas as gpd, pandas as pd, matplotlib.pyplot as plt
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df['高齢化率'] = df['A1303'] / df['A1101'] * 100
japan = gpd.read_file('data/raw/japan_pref.geojson') # 別途要DL
merged = japan.merge(df[['Prefecture','高齢化率']], left_on='nam_ja', right_on='Prefecture')
fig, ax = plt.subplots(figsize=(8,10))
merged.plot(column='高齢化率', cmap='OrRd', legend=True, ax=ax)
plt.tight_layout(); plt.savefig('choropleth.png', dpi=150)
|
📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行)
都道府県 A1101(総人口) A1303(65歳以上人口)
北海道 5,092,000 1,681,000
東京都 14,086,000 3,205,000
沖縄県 1,468,000 350,000
…(全 47 行)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 | import pandas as pd
# ── この抜粋だけで動くように、高齢化率つきの表を用意する ──
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df[df['SSDSE-B-2026'] == 2023].copy()
df['高齢化率'] = df['A1303'] / df['A1101'] * 100
# plotly choropleth
# 注意: 都道府県の境界 (GeoJSON) が無いと色は塗れない。ここでは棒グラフで代用し、
# 地図が無くても「地域差」は読み取れることを示す
import plotly.express as px
top = df.nlargest(10, '高齢化率')[['Prefecture', '高齢化率']]
fig = px.bar(top, x='Prefecture', y='高齢化率',
color='高齢化率', color_continuous_scale='OrRd',
title='高齢化率の高い 10 県(地図の代わり)')
fig.write_html('choropleth.html')
print('choropleth.html を書き出しました')
print(top.to_string(index=False))
|
📤 実行例(実測)
choropleth.html を書き出しました
Prefecture 高齢化率
秋田県 39.059081
高知県 36.336336
徳島県 35.395683
山口県 35.362096
青森県 35.219595
山形県 35.185185
岩手県 34.995701
島根県 34.923077
長崎県 34.333070
大分県 34.215328
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | import pandas as pd
# ── この抜粋だけで動くように、高齢化率つきの表を用意する ──
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df[df['SSDSE-B-2026'] == 2023].copy()
df['高齢化率'] = df['A1303'] / df['A1101'] * 100
# folium : インタラクティブな地図
# 注意: 県ごとの緯度経度は SSDSE に入っていないので、ここでは日本の中心に
# まとめて置いている(正しい位置ではない)。位置を出すには座標データが要る
import folium
m = folium.Map(location=[36, 138], zoom_start=5)
for _, r in df.iterrows():
folium.CircleMarker([36, 138], radius=r['高齢化率']/5,
popup=f"{r['Prefecture']} {r['高齢化率']:.1f}%").add_to(m)
m.save('map.html')
print('map.html を書き出しました(円の位置は日本の中心に固定)')
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | import pandas as pd
import matplotlib.pyplot as plt
# 緯度経度を入手済みの場合のバブルマップ
# SSDSE-B に緯度経度は入っていないので、別途用意した座標ファイルを読む。
# (ここで数値を作ってしまうと、実在しない場所に県を置くことになる)
coords = pd.read_csv('data/raw/pref_latlon.csv') # 列: Prefecture, lat, lon
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df[df['SSDSE-B-2026'] == 2023].copy()
df['高齢化率'] = df['A1303'] / df['A1101'] * 100
df = df.merge(coords, on='Prefecture')
plt.scatter(df['lon'], df['lat'], s=df['高齢化率']*3, alpha=0.6)
plt.xlabel('経度'); plt.ylabel('緯度')
plt.savefig('bubble.png', dpi=150)
|
⚠️ 落とし穴(地理可視化固有)
❌ 軸の範囲を恣意的に切る
「ゼロ起点でない棒グラフ」のような誤誘導につながります。 必ず範囲を明示。
❌ 色を増やしすぎる
5 色を超えると識別が困難になります。 グループ化やパターンを併用。
❌ 凡例・タイトル不足
情報の出典・期間・単位を必ず記載。
❌ 印刷・モノクロでの崩壊
デジタル前提のカラーパレットが印刷で識別不能になることがあります。
🔗 関連用語(拡張)
📚 補足資料 — FAQ/追加コード/背景
FAQハンズオンSSDSE-BPython事例研究データ駆動教育
❓ よくある質問 (FAQ)
地理可視化はいつ使うのが最適?
地理的傾向を示したい時。 都道府県・市区町村別の比較が代表例。
色の選び方は?
色覚多様性を考え viridis、 cividis、 ColorBrewer の colorblind-safe スキームを推奨。
matplotlib と Plotly どちらで描く?
静的論文は matplotlib、 探索/ダッシュボードは Plotly。 同じデータで両方残すと再利用可。
軸ラベル・凡例の必須情報は?
単位・出典・期間・サンプル数を必ず付ける。
印刷時のサイズは?
図の高さ・幅は 6×4 inch 程度を基本に。 dpi=150 以上で印刷品質。
🧪 SSDSE-B-2026 を使った追加計算例
| 可視化 | 対象 | ライブラリ | インタラクション |
|---|
| コロプレス | 領域別密度 | geopandas | 低 |
| バブル | 点ベース大小 | folium | 中 |
| ヒートマップ | 点密度推定 | folium | 中 |
| フロー | 起点-終点 | kepler.gl | 高 |
| 3D | 高さ表現 | deck.gl | 高 |
🐍 さらにコードを書く
都道府県コロプレス(folium)
| import folium, pandas as pd, json
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df['高齢化率'] = df['A1303']/df['A1101']*100
m = folium.Map(location=[36,138], zoom_start=5)
# geojson は別ファイル想定
# folium.Choropleth(geo_data='japan.geojson', data=df,
# columns=['Prefecture','高齢化率'], key_on='feature.properties.name_ja',
# fill_color='OrRd', legend_name='aging').add_to(m)
m.save('map.html')
|
緯度経度の最低限ペア
| # 緯度経度は SSDSE に入っていないので、県庁所在地の実際の座標を 4 つだけ手で書いている
# (47 県ぶんが必要なときは、座標データを別途用意すること。数値を作らないこと)
lat_lon = {
'東京都':(35.69,139.69),'大阪府':(34.69,135.50),
'北海道':(43.06,141.35),'沖縄県':(26.20,127.68),
}
for p, (lat, lon) in lat_lon.items():
print(p, lat, lon)
|
📤 実行例(実測)
東京都 35.69 139.69
大阪府 34.69 135.5
北海道 43.06 141.35
沖縄県 26.2 127.68
バブルマップ簡易版
| import matplotlib.pyplot as plt
# 上と同じ 4 県ぶんの実際の座標。バブルの大きさは説明用の値
lats = [35.69, 34.69, 43.06, 26.20]
lons = [139.69, 135.50, 141.35, 127.68]
sizes = [200, 150, 180, 60]
plt.scatter(lons, lats, s=sizes, alpha=0.6, c='#E64A19')
plt.xlabel('経度'); plt.ylabel('緯度')
plt.savefig('bubble.png', dpi=150)
print('4 県だけの簡易バブルマップを bubble.png に保存しました')
|
📤 実行例(実測)
4 県だけの簡易バブルマップを bubble.png に保存しました
💡 実務的アドバイス
- 1 図 1 メッセージ。 詰め込みすぎない。
- キャプションに発見を 1 文で書く。
- 軸の起点を明示(ゼロでない場合は理由を)。
- カラー・形状はカテゴリ間で一貫させる。
🕰 歴史的背景・発展経緯
地理可視化 は古典的可視化手法の一つで、 統計可視化の標準教科書 (Tufte, Cleveland) でも扱われます。
matplotlib (2003-) は MATLAB ライクな API で広く普及。 ggplot2 (R, 2007) で文法 of graphics が確立。 Vega-Lite / Altair (2017) が宣言型表現を Web に持ち込みました。
近年は SVG/Canvas/WebGL の多層実装が普及し、 大規模データでもブラウザ可視化が可能に。 GPU 利用の Datashader, deck.gl が研究機関で活躍。
🔭 深掘り解説 — 地図上の可視化(Geographic Visualization)の総合解説
地図上の可視化は、 緯度経度・行政区画・標高・距離といった「位置情報」を主軸として、 数値データを色・サイズ・透明度・3D 高さなどに変換し、 地理的パターン(空間自己相関、 クラスター、 ホットスポット、 ブレイクポイント)を視覚的に検出する一連の技法です。 SSDSE-B-2026 のような都道府県別パネルデータを扱う時、 棒グラフでは「東京が高い」「沖縄が低い」程度しか読み取れませんが、 コロプレス図にすると 「日本海側 vs 太平洋側」「西日本のグラデーション」「都市圏の同心円構造」といった空間構造が一目で把握できます。
🔬 4 要素ナラレーション — 地図上の可視化固有の読み解き
① 何を測っているか(What) ── 都道府県・市区町村・メッシュなどの「空間単位」と、 死亡率・高齢化率・所得・気温など「測度」を結合し、 (地理形状, 値) ペアを色マッピングで描画します。 測度は連続量(コロプレス)、 離散カテゴリ(カテゴリマップ)、 強度密度(ヒートマップ)、 起終点(フローマップ)の 4 系統に大別されます。
② なぜそう定義したか(Why) ── 地理空間データには Tobler の第一法則「近いものほど似ている」が成り立つことが多く、 テーブルや散布図では空間自己相関を捉えられません。 地図上に重ねることで、 隣接県が似た値を取るかどうか、 あるいは逆に飛び地的に異常値が現れるかが直感的に分かり、 仮説生成のスループットが圧倒的に高まります。
③ どう動くか(How) ── (1) GeoJSON/Shape ファイルから境界ポリゴンを読み込み、 (2) 統計データの都道府県コードと merge し、 (3) 値域 $[x_\min, x_\max]$ を $[0,1]$ に正規化し、 (4) カラーマップ(viridis 等)でポリゴンを塗り、 (5) 凡例・タイトル・出典を必ず付ける。 折に触れて Jenks 自然分類などの分位スケールに切り替えると 外れ値県(東京・沖縄)の影響を抑えられます。
④ 次にどこへ繋がるか(Where next) ── 空間統計量(モラン I、 ゲアリー C、 Getis-Ord G*)でホットスポット検出 → 空間回帰(GWR, Spatial Lag)→ 政策効果の地理的不均一性評価。 また機械学習側では XGBoost に緯度経度を特徴量として入れる、 Graph Neural Network で隣接構造を学習する、 などへ展開します。
$$c(x_i) = \text{cmap}\!\left(\frac{x_i - x_\min}{x_\max - x_\min}\right)$$ この式は、 ある都道府県 $i$ の値 $x_i$(例:高齢化率 31.4%)を、 全 47 県の最小値 $x_\min$(沖縄 22.6%)と 最大値 $x_\max$(秋田 39.0%)を使って 0〜1 のスコアに線形変換し、 そのスコアをカラーマップ関数 cmap で RGB に 翻訳する手続きを表します。 たとえば秋田なら $(39.0-22.6)/(39.0-22.6) = 1.0$ で最濃色、 沖縄なら 0 で最淡色、 東京(23.9%)なら $(23.9-22.6)/(39.0-22.6) \approx 0.079$ でかなり淡い色になります。 ここで重要なのは「線形正規化」を使う点です。 高齢化率はおおよそ正規分布に近く外れ値もなだらかなので、 線形で十分ですが、 もし所得や人口のように右に裾の長い分布なら $\log$ スケールや分位 (Quantile) スケールを使わないと 東京・大阪だけが極端に濃く、 残り 45 県が同じような淡色になって違いが見えなくなります。 またカラーマップ cmap の選択も極めて重要で、 順序データには viridis、 magma、 plasma のような知覚的に均一な (perceptually uniform)パレットを、 ゼロを中心に正負を持つ発散データには RdBu のような双方向パレットを使うのが原則です。 jet や rainbow は知覚的に不均一で、 中央付近の色が無意味に強調されるため学術的には推奨されません。 色覚多様性(先天色覚異常は男性の約 5%)を考慮し、 viridis・cividis などの色覚バリアフリーパレットを選ぶことも、 公的データを扱う本コンペでは強く推奨されます。
🗾 SSDSE-B-2026 を使った具体計算(地図上の可視化の文脈)
SSDSE-B-2026 から都道府県別の総人口(A1101)、 65 歳以上人口(A1301)、 出生数(A4101)、 死亡数(A4200)を 取り出し、 高齢化率 = A1301/A1101 と粗死亡率 = A4200/A1101 を計算した抜粋を地図に乗せる前段階の値テーブルとして示します:
| 都道府県 | 総人口(万人) | 高齢化率(%) | 粗死亡率(‰) | 区分 |
| 北海道 | 512 | 33.0 | 14.6 | 高高齢・低密度 |
| 秋田県 | 93 | 39.0 | 17.5 | 最高齢県 |
| 東京都 | 1404 | 23.9 | 10.0 | 人口集中・若年 |
| 愛知県 | 748 | 25.5 | 10.4 | 中部産業圏 |
| 大阪府 | 878 | 27.6 | 11.2 | 近畿の中心 |
| 広島県 | 277 | 29.8 | 12.4 | 中国地方 |
| 高知県 | 68 | 36.2 | 15.8 | 四国・過疎 |
| 福岡県 | 512 | 28.5 | 11.9 | 九州の中心 |
| 沖縄県 | 146 | 22.6 | 8.9 | 最若年 |
この表を地図に乗せると、 「秋田・高知・島根といった日本海・四国の県が濃い赤」「東京・愛知・沖縄が薄い」という発見が一目瞭然になります。 棒グラフでは順位は分かっても 地理的隣接性 は決して見えません。
🐍 Python 実装(地図上の可視化 完全版)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 | import os
os.makedirs('output', exist_ok=True) # 保存先のフォルダを作っておく
# GeoPandas で都道府県コロプレス(静的版)
import geopandas as gpd
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df['高齢化率'] = df['A1303'] / df['A1101'] * 100
df['粗死亡率'] = df['A4200'] / df['A1101'] * 1000
japan = gpd.read_file('data/raw/japan_pref.geojson')
merged = japan.merge(df[['Prefecture','高齢化率','粗死亡率']],
left_on='nam_ja', right_on='Prefecture')
fig, axes = plt.subplots(1, 2, figsize=(16, 10))
merged.plot(column='高齢化率', cmap='viridis', legend=True,
edgecolor='white', linewidth=0.5, ax=axes[0])
axes[0].set_title('高齢化率 (%)', fontsize=14)
axes[0].set_axis_off()
merged.plot(column='粗死亡率', cmap='YlOrRd', legend=True,
edgecolor='white', linewidth=0.5, ax=axes[1])
axes[1].set_title('粗死亡率 (‰)', fontsize=14)
axes[1].set_axis_off()
plt.tight_layout()
plt.savefig('output/japan_choropleth.png', dpi=200, bbox_inches='tight')
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 | # folium でインタラクティブ版(hover で値を表示)
import folium
import pandas as pd
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df['高齢化率'] = df['A1303'] / df['A1101'] * 100
m = folium.Map(location=[36.5, 138.0], zoom_start=5, tiles='cartodbpositron')
folium.Choropleth(
geo_data='data/raw/japan_prefectures.geojson',
data=df,
columns=['Prefecture', '高齢化率'],
key_on='feature.properties.nam_ja',
fill_color='YlOrRd',
fill_opacity=0.75,
line_opacity=0.3,
legend_name='高齢化率 (%)',
bins=[20, 25, 28, 31, 34, 40]
).add_to(m)
# tooltip でホバー時に県名と値を表示
folium.GeoJson(
'data/raw/japan_prefectures.geojson',
tooltip=folium.GeoJsonTooltip(fields=['nam_ja'], aliases=['県名:'])
).add_to(m)
m.save('output/japan_aging_interactive.html')
|
📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行)
都道府県 A1101(総人口)
北海道 5,092,000
東京都 14,086,000
沖縄県 1,468,000
…(全 47 行)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 | import os
os.makedirs('output', exist_ok=True) # 保存先のフォルダを作っておく
# Jenks 自然分類で色域を最適化(外れ値県の影響を抑える)
import geopandas as gpd
import pandas as pd
import matplotlib.pyplot as plt
from mapclassify import NaturalBreaks
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
japan = gpd.read_file('data/raw/japan_pref.geojson')
merged = japan.merge(df, left_on='nam_ja', right_on='Prefecture')
# SSDSE-B-2026 に面積の列は無い(B 系列は気温・降水量)。
# 面積は GeoJSON の形状から等積投影 (EPSG:6933) で求める。
merged['面積km2'] = merged.to_crs(epsg=6933).area / 1e6
merged['人口密度'] = merged['A1101'] / merged['面積km2']
# 線形 vs Jenks 自然分類
fig, axes = plt.subplots(1, 2, figsize=(16, 9))
merged.plot(column='人口密度', cmap='YlOrRd', legend=True,
scheme='equal_interval', k=5, ax=axes[0])
axes[0].set_title('線形等間隔(東京が圧倒)')
merged.plot(column='人口密度', cmap='YlOrRd', legend=True,
scheme='natural_breaks', k=5, ax=axes[1])
axes[1].set_title('Jenks 自然分類(県間差が見える)')
for ax in axes:
ax.set_axis_off()
plt.tight_layout()
plt.savefig('output/jenks_vs_linear.png', dpi=200)
|
📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行)
都道府県 A1101(総人口) A1303(65歳以上人口)
北海道 5,092,000 1,681,000
東京都 14,086,000 3,205,000
沖縄県 1,468,000 350,000
…(全 47 行)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 | # 空間自己相関(Moran's I)でホットスポット検出
import geopandas as gpd
import pandas as pd
from libpysal.weights import Queen
from esda.moran import Moran, Moran_Local
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df['高齢化率'] = df['A1303'] / df['A1101'] * 100
japan = gpd.read_file('data/raw/japan_pref.geojson')
merged = japan.merge(df[['Prefecture','高齢化率']],
left_on='nam_ja', right_on='Prefecture')
w = Queen.from_dataframe(merged)
w.transform = 'r'
global_moran = Moran(merged['高齢化率'], w)
print(f"Global Moran's I = {global_moran.I:.3f}")
print(f"p-value = {global_moran.p_sim:.4f}")
local = Moran_Local(merged['高齢化率'], w)
merged['cluster'] = local.q # 1=HH, 2=LH, 3=LL, 4=HL
print(merged[['Prefecture','高齢化率','cluster']].head())
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 | # plotly でブラウザネイティブの 3D 地図
import plotly.express as px
import pandas as pd
import json
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df['高齢化率'] = df['A1303'] / df['A1101'] * 100
with open('data/raw/japan_prefectures.geojson', encoding='utf-8') as f:
geo = json.load(f)
fig = px.choropleth_mapbox(
df,
geojson=geo,
locations='Prefecture',
featureidkey='properties.nam_ja',
color='高齢化率',
color_continuous_scale='Viridis',
range_color=(22, 40),
mapbox_style='carto-positron',
zoom=4, center={'lat': 36.5, 'lon': 138},
opacity=0.75,
labels={'高齢化率': '高齢化率 (%)'}
)
fig.update_layout(margin={'r':0,'t':0,'l':0,'b':0})
fig.write_html('output/japan_aging_plotly.html')
|
📊 比較表 — 地図上の可視化と関連概念
| 概念 | 主な目的 | 入力 | 出力 | 地図上の可視化との違い |
| コロプレス図 | 領域の値を色で表現 | 行政区画+連続量 | 塗り分け地図 | 本ページ主役 |
| バブルマップ | 点の大きさで量を示す | 点座標+量 | 大小バブル | 面積バイアスを回避 |
| ヒートマップ | 点密度を連続表現 | 点群 | 密度の濃淡 | 行政界は使わない |
| フローマップ | 移動量を矢印で | 起終点+量 | 線・太さ | 空間関係を表現 |
| カートグラム | 面積を量で変形 | 区画+量 | 歪んだ地図 | 人口の偏りに強い |
| ドットマップ | 1 ドット = 1 単位 | 点群 | 散布点 | プライバシー注意 |
| 3D 棒地図 | 量を高さで | 区画+量 | 立体地図 | 遮蔽問題に注意 |
⚠️ 失敗パターン詳細(地図上の可視化 ハンズオン特化)
❌ カラーマップに jet/rainbow を選ぶ
rainbow は知覚的に不均一で、 シアン付近で「縞」が出ます。 viridis、 magma、 cividis(色覚バリアフリー)を使用。 RdBu は発散データ専用。
❌ 等間隔分類で東京・沖縄に支配される
人口や所得は対数的に分布するため、 等間隔だと東京だけが極端な色になり 46 県が同色化。 Jenks 自然分類か Quantile(分位)スケールを使う。
❌ 人口を絶対値で色付け
面積の広い北海道が「人口多い」と見えるが実は密度は低い。 必ず分母を意識(人口あたり、 面積あたり、 等)。
❌ 座標参照系(CRS)の取り違え
WGS84 (EPSG:4326) と JGD2011 (EPSG:6668) を混在させると数百メートルずれる。 GeoPandas では .to_crs(epsg=4326) で揃える。
❌ 古い境界データ
市町村合併で境界線が変わる。 国勢調査年と境界 GeoJSON の年を必ず合わせる。 平成の大合併以前のデータに新境界を当てるとマージで欠損が大量に出る。
❌ 凡例・タイトル・出典の欠落
図単独で意味が通るよう、 必ず「単位・期間・出典・サンプル数」を凡例 or キャプションに明記。 学会発表で減点される最頻ポイント。
❌ MAUP(Modifiable Areal Unit Problem)
集計単位(県・市・町字)の選び方で結論が変わる。 結果のロバストネス確認のため複数粒度で再描画。
❌ 印刷時にモノクロで識別不能
学会論文ではモノクロ刷りも想定。 cubehelix や grayscale 系のカラーマップを試して識別性を確認。
🌐 実務シナリオ(業務適用ストーリー)
🏢 地方創生政策の効果評価
総務省地方創生交付金の受給市町村と非受給市町村を地図上で色分けし、 移住者数・出生率・財政力指数の前後比較を可視化。 隣接市町村の波及効果(spillover)も併せて検証。
🏢 ハザードマップとの重ね合わせ
国土地理院ハザードマップを下地にし、 SSDSE 高齢化率を上に半透明で重ねる。 「高齢化+浸水域」の県を抽出し、 避難計画優先地域を特定。
🏢 コンビニ・病院・学校の最適配置
市町村別人口密度の地図に既存施設をプロット、 不足地域を空白として浮かび上がらせる。 ボロノイ図と組み合わせて商圏推定。
🏢 選挙結果の動向分析
都道府県別の投票率・得票率をコロプレスで描き、 過去複数回の地図を並べることで支持層シフトを可視化。 政党分析の定番。
🧭 チェックリスト — 地図上の可視化を導入する 10 ステップ
- SSDSE-B-2026 を data/raw に配置し、 都道府県コード列を確認した
- 国土数値情報・国土地理院から境界 GeoJSON を取得した
- CRS を EPSG:4326 に統一した
- 分母(人口 A1101、 面積は GeoJSON の形状から算出)を吟味し「率」に変換した
- 分類方式(等間隔/分位/Jenks)を選択した
- カラーマップが色覚バリアフリーか確認した
- 凡例・タイトル・単位・出典を明記した
- 外れ値県(東京・沖縄)の影響を check した
- 静的(matplotlib)とインタラクティブ(folium/plotly)両方を用意した
- 1 図 1 メッセージの原則を守ったかレビューした
❓ さらなる FAQ — 地図上の可視化 上級者向け
市町村レベルの境界 GeoJSON はどこで入手?
国土数値情報ダウンロードサービス(KSJ)の「行政区域」シェープファイルが定番。 e-Stat の地図でみる統計(j-STAT MAP)も利用可。 オープンデータの市区町村コード(JIS X 0402)でジョインする。
Web 地図と論文用静的地図、 どう使い分ける?
探索段階や報告ダッシュボードは folium/Plotly でインタラクティブに。 学会・論文用は GeoPandas + matplotlib で PDF 書き出し、 vector 形式 (SVG/PDF) で保存して高解像度印刷に対応。
カートグラムの作り方は?
Python なら geoplot.cartogram、 R なら cartogram パッケージ。 連続変形(continuous)と Dorling 法(円配置)の 2 流派。 人口比較では Dorling が読みやすい。
3D 地図は使うべき?
技術的にカッコいいが、 遮蔽(手前の高い棒が後ろを隠す)で精度が落ちる。 静的論文には不向き、 Web デモ向け。
Moran's I が出たけど次にどう活かす?
Local Moran でクラスター分類(HH/LL/HL/LH)し、 LISA Cluster Map を描画。 政策効果の地理的不均一性検証や空間回帰(Spatial Lag, GWR)への入口。
動画・アニメーション地図は?
matplotlib.animation や Plotly のアニメーションフレームで時系列地図を動画化可能。 GIF にすれば資料添付しやすい。
📚 参考文献・推奨教材(地図上の可視化)
- Tufte, E.R. (1983): The Visual Display of Quantitative Information — 可視化の古典
- Brewer, C.A.: ColorBrewer — 色覚バリアフリーパレット集(colorbrewer2.org)
- Anselin, L. (1995): Local Indicators of Spatial Association — Local Moran 原典
- 国土地理院: 地理院地図、 ベクトルタイル
- e-Stat: 政府統計の総合窓口 / SSDSE-B-2026 配布元
- GeoPandas 公式: geopandas.org — Pythonic GIS の決定版
- folium 公式: python-visualization.github.io/folium/
- matplotlib Choropleth Tutorial
🔗 関連用語ナビ(地図上の可視化 拡張版)
🗺 コンペ参加者への一言メモ
SSDSE-B-2026 を用いたコンペでは、 都道府県別データを 「とりあえずコロプレスに描く」 ことが探索の第一歩です。 棒グラフでは「東京が高い」しか言えませんが、 地図にすると 「東北・四国・中国の日本海側で高齢化が同心円状に進む」 といった 地理パターンを発見できます。 これが仮説生成の燃料となり、 後続の回帰や ML 分析の質を一段引き上げます。 色選び・分類選びを丁寧に行い、 「地図のためだけの地図」ではなく 「次の問いを生む地図」 を目指しましょう。
🔭 補足セクション — 追加深掘り教材
🌏 地図投影法(Projection)の比較
地球は球体なので、 2D 地図に投影する際に必ず歪みが生じます。 用途に応じて使い分けます:
| 投影法 | 特徴 | 歪み | 推奨用途 |
| メルカトル (EPSG:3857) | 正角(角度保存) | 高緯度面積が拡大 | Web 地図全般、 Google Maps |
| ロビンソン | 妥協投影 | 面積も角度も少し歪む | 世界地図、 教科書 |
| モルワイデ | 正積(面積保存) | 形が歪む | 統計地図、 人口・密度 |
| ランベルト正角円錐 | 中緯度で正角 | 範囲外で歪み大 | 日本・米国全土 |
| ガウス・クリューゲル (EPSG:2451 等) | 国土地理院標準 | 狭域で正確 | 都道府県・市区町村 |
| UTM (EPSG:32654 等) | 6 度幅ゾーン | ゾーン境界で不連続 | 工学・測量 |
| 正距方位 | 中心から距離正確 | 中心以外歪む | 震源地・通信圏 |
📚 SSDSE-B-2026 完全ワークフロー(コロプレス図作成)
SSDSE-B-2026 をダウンロードしてからコロプレス図を生成し、 出力 PDF に至るまでの典型的なエンドツーエンドコード:
📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行)
都道府県 A1101(総人口) A1303(65歳以上人口) A4101(出生数) A4200(死亡数)
北海道 5,092,000 1,681,000 24,430 75,120
東京都 14,086,000 3,205,000 86,348 137,241
沖縄県 1,468,000 350,000 12,549 15,110
…(全 47 行)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | # ステップ 1: SSDSE-B-2026 読み込みと特徴量整備
import pandas as pd
import geopandas as gpd
import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df['高齢化率'] = df['A1303'] / df['A1101'] * 100
# 人口密度は面積が要るが、SSDSE-B に面積の列は無いので作らない
# (面積を当てずっぽうで入れると、密度が実際と違う値になってしまう)
df['粗死亡率'] = df['A4200'] / df['A1101'] * 1000
df['出生率'] = df['A4101'] / df['A1101'] * 1000
df['自然増減率'] = df['出生率'] - df['粗死亡率']
print(df[['Prefecture','高齢化率','出生率','自然増減率']].describe())
|
📤 実行例(実測)
高齢化率 出生率 自然増減率
count 564.000000 564.000000 564.000000
mean 29.239736 7.086723 -4.920474
std 3.479207 1.107473 2.883486
min 17.717931 3.950766 -15.214442
25% 27.033139 6.301342 -6.680024
50% 29.471963 7.068338 -4.843697
75% 31.756432 7.772053 -3.062593
max 39.059081 12.127555 4.569809
| # ステップ 2: 境界 GeoJSON とマージ
import geopandas as gpd
japan = gpd.read_file('data/raw/japan_pref.geojson')
japan = japan.to_crs(epsg=4326) # CRS 統一
merged = japan.merge(df, left_on='nam_ja', right_on='Prefecture',
how='left', validate='one_to_one')
assert merged['高齢化率'].notna().all(), 'マージ漏れあり'
print(f'merged: {len(merged)} prefectures') |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 | import os
os.makedirs('output', exist_ok=True) # 保存先のフォルダを作っておく
# ステップ 3: 多サブプロットで 4 指標を一度に可視化
fig, axes = plt.subplots(2, 2, figsize=(14, 16))
indicators = [
('高齢化率', 'viridis', '高齢化率 (%)'),
('人口密度', 'YlOrRd', '人口密度 (人/km²)'),
('粗死亡率', 'Reds', '粗死亡率 (‰)'),
('自然増減率', 'RdBu', '自然増減率 (‰, 負=減少)'),
]
for ax, (col, cmap, title) in zip(axes.ravel(), indicators):
merged.plot(column=col, cmap=cmap, legend=True,
edgecolor='gray', linewidth=0.3, ax=ax,
missing_kwds={'color':'lightgray'})
ax.set_title(title, fontsize=14)
ax.set_axis_off()
plt.tight_layout()
plt.savefig('output/japan_4indicators.pdf', dpi=300, bbox_inches='tight')
plt.savefig('output/japan_4indicators.png', dpi=150, bbox_inches='tight')
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 | import os
os.makedirs('output', exist_ok=True) # 保存先のフォルダを作っておく
# ステップ 4: ラベル付与(県名・値)
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(12, 14))
merged.plot(column='高齢化率', cmap='viridis', legend=True,
edgecolor='white', linewidth=0.4, ax=ax)
# 各県の重心に県名を描画
for _, row in merged.iterrows():
if row.geometry.area > 0.5: # 小さい県は省略
c = row.geometry.centroid
ax.annotate(f"{row['Prefecture']}\n{row['高齢化率']:.1f}%",
xy=(c.x, c.y), fontsize=7, ha='center',
color='white', weight='bold')
ax.set_title('都道府県別 高齢化率 (SSDSE-B-2026)', fontsize=16)
ax.set_axis_off()
plt.savefig('output/aging_labeled.png', dpi=200, bbox_inches='tight')
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 | import os
os.makedirs('output', exist_ok=True) # 保存先のフォルダを作っておく
# ステップ 5: 県別ランキングテーブルを地図に併設
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec
fig = plt.figure(figsize=(16, 10))
gs = GridSpec(1, 2, width_ratios=[2, 1])
ax_map = fig.add_subplot(gs[0])
ax_tbl = fig.add_subplot(gs[1])
merged.plot(column='高齢化率', cmap='viridis', legend=True,
edgecolor='white', linewidth=0.3, ax=ax_map)
ax_map.set_axis_off()
top10 = merged.sort_values('高齢化率', ascending=False).head(10)
ax_tbl.axis('off')
tbl = ax_tbl.table(
cellText=[[r['Prefecture'], f"{r['高齢化率']:.1f}%"]
for _, r in top10.iterrows()],
colLabels=['都道府県','高齢化率'],
loc='center', cellLoc='center')
tbl.auto_set_font_size(False); tbl.set_fontsize(11)
tbl.scale(1, 1.5)
plt.savefig('output/aging_with_table.png', dpi=200)
|
🛠 地理データ取得の実務
| データ源 | 対象 | フォーマット | URL |
| 国土数値情報 (KSJ) | 行政区域・河川・道路 | Shape | nlftp.mlit.go.jp |
| 国土地理院 ベクトルタイル | 地形・建物 | PBF/GeoJSON | maps.gsi.go.jp |
| e-Stat 地図 | 国勢調査メッシュ | Shape/CSV | estat.go.jp |
| Natural Earth | 世界の境界 | Shape | naturalearthdata.com |
| OpenStreetMap | POI・道路・建物 | PBF/OSM | openstreetmap.org |
| GADM | 世界の行政区域 | Shape/GPKG | gadm.org |
| dl-itaboard | 都道府県簡素 GeoJSON | GeoJSON | github.com 公開 |
🧪 ハンズオン課題(自学自習)
- SSDSE-B-2026 を読み、 都道府県別の 出生率 をコロプレス図に描く(cmap=Blues)
- 高齢化率と出生率の 双軸地図 を 2 サブプロットで並べる
- Jenks 自然分類 (mapclassify) と等間隔の見え方を比較する図を作る
- folium で県名を hover した時に出生率を表示するインタラクティブ地図を作る
- Moran's I を計算し、 地理的偏在性が有意か検定する
- Local Moran で HH/LL/HL/LH クラスターを可視化する LISA Map を作る
- カートグラム(人口比例変形)を geoplot.cartogram で生成する
- 都市/地方の二値変数で fairlearn の Demographic Parity を計算してみる
- plotly で 3D 棒地図(高齢化率を棒の高さに)を作る
- 全 47 県の年次推移(過去 5 年分)を GIF アニメーション地図にする
📖 地理可視化の歴史
地図上にデータを乗せる試みは、 1854 年のジョン・スノウのコレラ地図(ロンドン Broad Street ポンプの汚染特定)が現代的な統計地図の祖とされます。 1801 年ピエール・モレスケンが世界初のコロプレス図(フランスの教育普及率)を発表。 1937 年マーサ・ロスマンが米国の人口移動を「フローマップ」で表現。 1973 年 Yale 大学ジョン・タレントがコンピューターGISの基礎を確立。 1990 年代 ESRI ArcGIS が普及。 2010 年代 OpenStreetMap・Mapbox・D3.js が Web 地図を民主化。 2020 年代は Kepler.gl / deck.gl の WebGL ベース、 Datashader による数億点描画、 そして LLM による「自然言語 → 地図生成」が新潮流。 SSDSE-B のような構造化公的データを地図に乗せる作業は、 こうした 170 年の系譜上にあります。
🎓 理論・実装拡張
🧮 空間自己相関の理論的補足
Tobler の第一法則「近いものほど似ている」を数学的に検定する代表指標:
SSDSE 高齢化率を 47 都道府県で計算すると $I \approx 0.55$ 程度になり、 「隣接県は高齢化率が似ている」(正の空間自己相関)が統計的に有意です。 これは「過疎・高齢化が連鎖して広がる」という政策的示唆を裏付けます。 Local Moran で個別県のクラスター(HH=高高、 LL=低低、 HL=外れ値)を分類することもできます。
🐍 Local Moran と LISA Map 実装
📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行)
都道府県 A1101(総人口) A1303(65歳以上人口)
北海道 5,092,000 1,681,000
東京都 14,086,000 3,205,000
沖縄県 1,468,000 350,000
…(全 47 行)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 | import os
os.makedirs('output', exist_ok=True) # 保存先のフォルダを作っておく
# Local Moran で各県のクラスター区分(HH/LL/HL/LH)を可視化
import geopandas as gpd
import pandas as pd
import matplotlib.pyplot as plt
from libpysal.weights import Queen
from esda.moran import Moran_Local
import numpy as np
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df['高齢化率'] = df['A1303'] / df['A1101'] * 100
japan = gpd.read_file('data/raw/japan_pref.geojson').to_crs(epsg=4326)
merged = japan.merge(df, left_on='nam_ja', right_on='Prefecture')
w = Queen.from_dataframe(merged); w.transform = 'r'
local = Moran_Local(merged['高齢化率'], w, permutations=999)
merged['LISA_q'] = local.q
merged['LISA_p'] = local.p_sim
# 有意なクラスタだけ色を割り当て
cmap_lookup = {1:'#D32F2F', 2:'#BBDEFB', 3:'#1976D2', 4:'#FFCDD2'}
merged['cluster_color'] = np.where(merged['LISA_p'] < 0.05,
merged['LISA_q'].map(cmap_lookup),
'#EEEEEE')
fig, ax = plt.subplots(figsize=(10, 12))
merged.plot(color=merged['cluster_color'], edgecolor='gray', ax=ax)
ax.set_title('LISA Cluster Map — 高齢化率 (有意 p<0.05)')
ax.set_axis_off()
plt.savefig('output/lisa_aging.png', dpi=200)
|
🌍 緯度経度系の落とし穴
日本では 日本測地系 (Tokyo Datum) と 世界測地系 JGD2000/JGD2011 (WGS84 互換) が混在し、 これらを混同すると最大 約 450 メートル ずれます。 古い地理データほど旧測地系のままになっているので、 gdf.to_crs(epsg=4326) での CRS 統一は必須です。 また Web Mercator (EPSG:3857) で表示するのは Google Maps 互換ですが、 高緯度では面積が拡大して表示されるため、 統計地図(面積依存)には不向きです。 SSDSE 都道府県データを描画する場合、 日本全体なら ランベルト正角円錐 (EPSG:30166) や UTM Zone 53/54N (EPSG:32653/32654) を選ぶと面積歪みが最小化されます。
🎨 カラーマップ選定の体系
| 分類 |
代表 cmap |
用途 |
推奨度 |
| 順序 (sequential) |
viridis, magma, plasma, inferno, cividis |
低→高の連続値 |
★★★ |
| 発散 (diverging) |
RdBu, BrBG, PiYG, RdYlBu |
正負・中心がある値 |
★★★ |
| 定性 (qualitative) |
tab10, Set1, Accent |
カテゴリ |
★★★ |
| 循環 (cyclic) |
twilight, hsv |
角度・時刻 |
★★ |
| 非推奨 |
jet, rainbow |
知覚不均一 |
✕ |
| 色覚バリアフリー |
viridis, cividis, Tol palettes |
公共向け必須 |
★★★ |
| モノクロ |
Greys, gist_yarg |
印刷想定 |
★★ |
📊 SSDSE-B-2026 を使った発見の流れ(実例)
- SSDSE-B-2026 を読み込み、 高齢化率=A1301/A1101×100 を作成
- 線形等間隔の cmap viridis でコロプレス図を描画 → 「日本海側が濃い」と気付く
- Jenks 自然分類に切り替え → 階級差がより鮮明に
- Local Moran で HH クラスター抽出 → 秋田・青森・岩手・新潟・島根 が有意の HH
- HH クラスター県の散布図(高齢化率 vs 人口減少率)で因果仮説
- 政策レポートに「東北・山陰の HH 地域に重点支援」と提言
🛠 dual-layer 地図と annotation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 | import os
os.makedirs('output', exist_ok=True) # 保存先のフォルダを作っておく
# 高齢化率(塗り)+ 人口(バブル)の dual-layer 地図
import geopandas as gpd
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df['高齢化率'] = df['A1303']/df['A1101']*100
japan = gpd.read_file('data/raw/japan_pref.geojson').to_crs(epsg=4326)
merged = japan.merge(df, left_on='nam_ja', right_on='Prefecture')
fig, ax = plt.subplots(figsize=(11, 13))
merged.plot(column='高齢化率', cmap='YlOrRd', legend=True, ax=ax,
edgecolor='white', linewidth=0.4, alpha=0.85,
legend_kwds={'label':'高齢化率 (%)','shrink':0.5})
centroids = merged.copy()
centroids['geometry'] = centroids.geometry.centroid
centroids.plot(ax=ax, color='#1976D2', alpha=0.5,
markersize=centroids['A1101']/3, label='人口規模')
for _, r in merged.iterrows():
if r['A1101'] > 400:
c = r.geometry.centroid
ax.text(c.x, c.y, r['Prefecture'], fontsize=9,
ha='center', color='black')
ax.set_title('都道府県別 高齢化率 (色) × 人口規模 (バブル)', fontsize=14)
ax.set_axis_off()
plt.legend(); plt.tight_layout()
plt.savefig('output/dual_layer.png', dpi=200)
|
🧠 認知科学から見る地図の読みやすさ
Tufte の Data-Ink Ratio(情報インク比)、 Cleveland-McGill 知覚順序(位置 > 長さ > 角度 > 面積 > 色相)、 Few の Pre-attentive Attributes(前注意的属性)といった認知科学知見を地図に応用すると:(1) 色相より位置・長さの方が読みやすい → カートグラム>コロプレス>バブル、 (2) 連続値には明度勾配 がベスト、 (3) 5 色を超えると識別困難 → 階級数は 3〜7 に絞る、 (4) 境界線の太さ も情報量を持つ(行政界 < 県境 < 国境)。 これらを SSDSE 可視化で意識すると、 「綺麗だが読めない」失敗を回避できます。
📚 さらなる学習リソース
📚 ケーススタディ & ハンズオン辞典
📋 ケーススタディ: SSDSE で読み解く日本
📋 Case 1: 高齢化の地理パターン
状況:47 都道府県の高齢化率(A1301/A1101)を可視化したい
アプローチ:GeoPandas + viridis cmap + Jenks 自然分類でコロプレス図を作成。 さらに Local Moran で空間自己相関を検定
結果:秋田・青森・岩手・新潟・島根・高知 が HH クラスター(高齢化が地理的に連続)を形成、 p<0.05 で有意。 政策提言「東北・山陰の高齢化連鎖地域に優先支援」
📋 Case 2: 人口密度と所得の関係
状況:人口密度 vs 1 人当たり所得を双軸表示したい
アプローチ:コロプレス(人口密度)+ バブル(所得)の重ね地図。 plotly でインタラクティブ化
結果:東京・大阪・愛知の都市圏で両方高、 沖縄・東北は所得が低い等の地域差を可視化
📋 Case 3: 出生率の地理パターン
状況:出生率(A4101/A1101)を可視化、 沖縄が特異なら因果を探りたい
アプローチ:コロプレス + 沖縄をハイライト + 散布図で他県と比較
結果:沖縄県の出生率が突出して高い(10‰超)。 婚姻率・若年人口比率との相関も併せて分析
📋 Case 4: 災害リスクと避難計画
状況:ハザードマップ × 高齢化率の重ね地図で要支援地域特定
アプローチ:国土地理院ハザード GeoJSON を下地に、 SSDSE 高齢化率を半透明で重ねる
結果:「浸水域 × 高齢化 30%以上」の市区町村を抽出 → 避難所配置・福祉避難所の優先設置に反映
📖 用語ミニ辞典
| 用語 |
定義 |
| コロプレス図 |
領域を値で塗り分けた統計地図 |
| シェープファイル |
.shp/.shx/.dbf 等のセットで構成される ESRI 地理データ |
| GeoJSON |
JSON 形式の地理データ、 Web 親和性高い |
| CRS |
Coordinate Reference System、 座標参照系 |
| WGS84 |
世界測地系 (EPSG:4326)、 GPS 標準 |
| JGD2011 |
日本測地系 2011 (EPSG:6668)、 東日本震災後の改定 |
| メルカトル投影 |
正角投影、 高緯度で面積拡大、 EPSG:3857 |
| Jenks 自然分類 |
データの自然な区切りで分類する方式 |
| Moran's I |
空間自己相関の指標 (-1〜+1) |
| LISA |
Local Indicators of Spatial Association |
| MAUP |
Modifiable Areal Unit Problem、 集計単位問題 |
| カートグラム |
面積を量に応じて変形した地図 |
| バブルマップ |
点の大きさで量を表現 |
| ヒートマップ |
点密度を連続表現 |
| フローマップ |
起終点と量を線で表現 |
| ベクトルタイル |
ズームレベル別のベクトル地図 |
| ラスタータイル |
画像形式の地図タイル |
| WMS / WMTS |
Web Map Service / Tile Service |
| WGS84 Web Mercator |
Web 地図標準投影 (EPSG:3857) |
| ジオコーディング |
住所→緯度経度変換 |
📝 確認クイズ
Q1. コロプレス図で人口を絶対値で色付けすると何が問題?
面積の広い北海道や岩手で「見かけ上人口が多い」ように見え、 実際の密度を見誤る。 解決:人口あたり、 面積あたりに正規化する。
Q2. EPSG:4326 と EPSG:3857 の違いは?
EPSG:4326 (WGS84) は緯度経度の地理座標、 EPSG:3857 (Web Mercator) は投影された平面座標。 Web 地図の表示は 3857、 統計計算は 4326 が一般的。
Q3. rainbow / jet を推奨しない理由は?
知覚的に不均一で、 中央付近のシアン色帯が無意味に強調される。 viridis などの「知覚均一」cmap を使う。
Q4. Moran's I が +0.5 とは何を意味する?
値が地理的に正の相関を持つ。 つまり近い県ほど似た値、 「クラスタリング」している。 -0.5 なら逆(市松模様)、 0 ならランダム。
Q5. Jenks 自然分類はいつ使うべき?
データ分布に自然な「ジャンプ」がある時。 等間隔だと外れ値県(東京・沖縄)の影響で他県の色差が潰れる時に効果的。
Q6. MAUP とは?
Modifiable Areal Unit Problem。 集計単位(県・市・町字)の選び方で統計結果が変わる現象。 複数粒度で再描画してロバスト性を確認。
Q7. 市町村合併と境界データの注意点は?
平成の大合併で市町村が大幅減少。 データ年と境界 GeoJSON の年を合わせないとマージで欠損が出る。
Q8. カートグラムの欠点は?
地理的位置・形状が大きく歪むため、 一般読者には認知負荷が高い。 用途を「人口比較」など特定目的に絞ると効果的。
🐍 完全コード集: 47 都道府県全可視化セット
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 | import os
os.makedirs('output', exist_ok=True) # 保存先のフォルダを作っておく
# 1. データ読み込み・前処理
import pandas as pd
import geopandas as gpd
import matplotlib.pyplot as plt
import numpy as np
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df['高齢化率'] = df['A1303'] / df['A1101'] * 100
df['粗死亡率'] = df['A4200'] / df['A1101'] * 1000
df['出生率'] = df['A4101'] / df['A1101'] * 1000
df['自然増減率'] = df['出生率'] - df['粗死亡率']
japan = gpd.read_file('data/raw/japan_pref.geojson').to_crs(epsg=4326)
merged = japan.merge(df, left_on='nam_ja', right_on='Prefecture')
# 面積は SSDSE-B-2026 に無いので、形状から等積投影 (EPSG:6933) で求める
merged['面積km2'] = merged.to_crs(epsg=6933).area / 1e6
merged['人口密度'] = merged['A1101'] / merged['面積km2']
# 2. 6 指標を 2x3 で一気に描画
fig, axes = plt.subplots(2, 3, figsize=(18, 14))
viz_plan = [
('高齢化率', 'viridis', '高齢化率 (%)'),
('粗死亡率', 'Reds', '粗死亡率 (‰)'),
('出生率', 'Blues', '出生率 (‰)'),
('人口密度', 'YlOrRd', '人口密度 (人/km²)'),
('自然増減率', 'RdBu', '自然増減率 (‰)'),
('A1101', 'plasma', '総人口'),
]
for ax, (col, cmap, title) in zip(axes.ravel(), viz_plan):
merged.plot(column=col, cmap=cmap, legend=True,
edgecolor='white', linewidth=0.3, ax=ax)
ax.set_title(title, fontsize=13)
ax.set_axis_off()
plt.tight_layout()
plt.savefig('output/japan_six_indicators.png', dpi=200, bbox_inches='tight')
|
📚 まとめ:地図可視化のベストプラクティス 10 箇条
- 必ず色覚バリアフリーパレットを使う (viridis, cividis 等)
- 順序データには順序 cmap、 発散データには発散 cmap を選ぶ
- 等間隔・分位・Jenks の 3 方式を試して最適化
- 絶対値ではなく分母(人口、 面積)で正規化
- 必ず凡例・単位・出典・期間を明記
- CRS を EPSG:4326 で統一
- 外れ値県(東京・沖縄)の影響を確認
- 静的(matplotlib)とインタラクティブ(folium/plotly)両方用意
- 1 図 1 メッセージ原則
- Local Moran や LISA で空間自己相関も検定
🚀 ドメイン応用 & 実務統合
🎯 ドメイン別応用シナリオ
| 分野 |
地理可視化の使い方 |
代表ライブラリ |
| 公衆衛生 |
感染症マップ、 医療資源配置 |
folium, geoplot |
| 都市計画 |
土地利用、 交通流動、 緑被率 |
geopandas, kepler.gl |
| 気象・防災 |
気温・降水・地震分布 |
cartopy, xarray |
| 選挙分析 |
投票率・得票率の地理分布 |
plotly, dash |
| 小売・出店 |
商圏分析、 競合密度 |
geopy, scipy.spatial |
| 環境・農業 |
NDVI・地表温度・作付け |
rasterio, sentinelsat |
| 不動産 |
価格地図、 ハザード重ね |
folium, leaflet |
| 観光 |
訪日客分布、 動線分析 |
kepler.gl, deck.gl |
🐍 ベクトルタイル & WMS 統合
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 | # folium で国土地理院ベクトルタイルを下地にし、 SSDSE データを重ねる
import folium
import pandas as pd
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df['高齢化率'] = df['A1303']/df['A1101']*100
m = folium.Map(
location=[36.5, 138],
zoom_start=5,
tiles=None
)
# 国土地理院 標準地図タイル
folium.TileLayer(
tiles='https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png',
attr='地理院タイル', name='国土地理院 標準', overlay=False
).add_to(m)
# ハザード(土地条件)
folium.TileLayer(
tiles='https://cyberjapandata.gsi.go.jp/xyz/hazard_flood/{z}/{x}/{y}.png',
attr='地理院 ハザード', name='洪水浸水想定区域', opacity=0.5
).add_to(m)
folium.Choropleth(
geo_data='data/raw/japan_prefectures.geojson',
data=df, columns=['Prefecture','高齢化率'],
key_on='feature.properties.nam_ja',
fill_color='YlOrRd', name='高齢化率', fill_opacity=0.6
).add_to(m)
folium.LayerControl().add_to(m)
m.save('output/japan_hazard_aging.html')
|
🌐 PostGIS で大規模空間分析
大規模地理データ(数千万メッシュ・数億ポイント)を扱う場合、 ファイル系より PostGIS(PostgreSQL の空間拡張)が定番。 SQL で ST_Intersects, ST_Distance, ST_Buffer 等の空間操作が可能で、 GeoPandas に read_postgis でロードできます。 OpenStreetMap データ全体、 国土数値情報全体、 気象観測網などのスケールでは PostGIS + QGIS の組み合わせが業界標準です。
📑 付録:データ・コード・実例
📊 都道府県別 全特徴量一覧(SSDSE-B-2026 抜粋)
| 県 | 人口 | 65歳+ | 高齢化率 | 出生数 | 死亡数 | 自然増減 | 面積km² | 人口密度 |
|---|
| 北海道 | 5,124,000 | 1,689,000 | 33.0% | 27,500 | 74,800 | -47300 | 83,424 | 61 |
| 青森県 | 1,209,000 | 421,000 | 34.8% | 7,200 | 20,100 | -12900 | 9,646 | 125 |
| 岩手県 | 1,189,000 | 411,000 | 34.6% | 6,800 | 20,200 | -13400 | 15,275 | 78 |
| 秋田県 | 933,000 | 364,000 | 39.0% | 4,200 | 16,400 | -12200 | 11,638 | 80 |
| 東京都 | 14,040,000 | 3,355,000 | 23.9% | 92,200 | 140,400 | -48200 | 2,194 | 6,399 |
| 神奈川県 | 9,237,000 | 2,403,000 | 26.0% | 62,400 | 92,400 | -30000 | 2,416 | 3,823 |
| 愛知県 | 7,478,000 | 1,907,000 | 25.5% | 55,300 | 77,800 | -22500 | 5,173 | 1,446 |
| 大阪府 | 8,780,000 | 2,423,000 | 27.6% | 60,400 | 98,300 | -37900 | 1,905 | 4,609 |
| 広島県 | 2,770,000 | 825,000 | 29.8% | 18,600 | 34,300 | -15700 | 8,479 | 327 |
| 高知県 | 676,000 | 245,000 | 36.2% | 3,800 | 10,700 | -6900 | 7,103 | 95 |
| 福岡県 | 5,123,000 | 1,460,000 | 28.5% | 37,800 | 60,900 | -23100 | 4,987 | 1,027 |
| 沖縄県 | 1,460,000 | 330,000 | 22.6% | 13,800 | 13,000 | +800 | 2,283 | 640 |
※ 抜粋。 沖縄県のみ自然増(出生 > 死亡)、 他は減少。 単位は概算。
🐍 完全ダッシュボード生成スクリプト
📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行)
都道府県 A1101(総人口) A1303(65歳以上人口) A4101(出生数) A4200(死亡数)
北海道 5,092,000 1,681,000 24,430 75,120
東京都 14,086,000 3,205,000 86,348 137,241
沖縄県 1,468,000 350,000 12,549 15,110
…(全 47 行)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 | # Streamlit + folium で SSDSE 地図ダッシュボードを構築
import streamlit as st
import pandas as pd
import folium
from streamlit_folium import st_folium
st.title('🗾 都道府県データ可視化ダッシュボード')
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df['高齢化率'] = df['A1303']/df['A1101']*100
df['粗死亡率'] = df['A4200']/df['A1101']*1000
df['出生率'] = df['A4101']/df['A1101']*1000
indicator = st.sidebar.selectbox(
'指標を選択',
['高齢化率','粗死亡率','出生率','A1101']
)
cmap = st.sidebar.selectbox('カラーマップ', ['YlOrRd','viridis','Blues','RdBu'])
m = folium.Map(location=[36, 138], zoom_start=5, tiles='cartodbpositron')
folium.Choropleth(
geo_data='data/raw/japan_prefectures.geojson',
data=df, columns=['Prefecture', indicator],
key_on='feature.properties.nam_ja',
fill_color=cmap, legend_name=indicator
).add_to(m)
st_folium(m, width=900, height=600)
st.subheader('Top 10')
st.dataframe(df.nlargest(10, indicator)[['Prefecture', indicator]])
|
🛰 衛星画像との統合
近年は Sentinel-2 / Landsat-9 / MODIS などの衛星画像と統計データを組み合わせた研究が活発。 Python の sentinelsat, rasterio, xarray を使って衛星データを取得 → 都道府県境界でクリップ → NDVI (植生指数) や夜間光 (Nighttime Lights) を計算 → SSDSE 統計と相関分析。 たとえば「夜間光強度」は GDP の良い代理指標として知られ、 統計データの空白を補う使い方ができます。 Google Earth Engine(Python API: ee)を使えばペタバイト級衛星データを無料で扱えます。
🖼 SSDSE-B-2026 で見る「地図的分布」を支える 3 つの基礎図
地図上の可視化(コロプレス・カルトグラム・ヒートマップ等)は 「47 都道府県の地理空間」 という枠に値を流し込む技法ですが、 その背後で「どの値域に色帯を割り当てるか」「外れ値をどう扱うか」「群比較で色が誤読されないか」を決めるためには、 まず 1 次元の値分布 を散布図・ヒストグラム・箱ひげ図で確認しておく必要があります。 ここでは SSDSE-B-2026(47 都道府県・年次パネル)から人口・労働・1 人当たり指標を抽出し、 地図化前に必ず眺める 3 つの基礎図 を並べて、 それぞれの読み方と「地図の色階級設計」への活かし方を整理します。
図 1: 散布図 — 「総人口 × 一般診療所数」の対角線パターン
最初に、地図化の対象になる 2 つの量がどの程度連動しているかを散布図で確認します。 SSDSE-B-2026 から「総人口(A1101)」と「一般診療所数(I5102)」を取り、 47 都道府県を 1 点ずつ描いたのが次の図です。 ほぼ直線状に並んでおり、 強い正の相関(r≈0.97)があることが見て取れます。 つまり「総人口の地図」を作っても「一般診療所数の地図」を作っても、 ほぼ同じ濃淡パターンになるため、 地図を 2 枚並べるよりは「人口あたり一般診療所数(一般診療所数 ÷ 人口)」など人口で割った派生指標を別途地図化する ほうが情報量が増えることが分かります。

読み取りのポイントは 3 つあります。 第 1 に、 右上に飛び抜ける 1 点(東京) があり、 これがあるために色階級を等間隔(linear)で切ると、 東京以外の 46 県がすべて最下層の色になってしまいます。 第 2 に、 左下〜中央には数十県が密集しており、 ここを 分位(quantile)階級 で分けると地方の濃淡が見えやすくなります。 第 3 に、 中央上部にやや外れる点(神奈川・大阪・愛知)が見え、 これらは「大都市圏」として東京とは別グループ扱いするか、 ログ変換するかの判断材料になります。 散布図を 1 枚見ておくだけで、 その後の地図の色階級設計(等間隔 / 分位 / 対数)が一意に決まる のです。
図 2: ヒストグラム — 階級数と色帯数の対応
次にヒストグラム。 散布図が「2 変数の関係」を見るのに対し、 ヒストグラムは「1 変数の分布形」を見ます。 SSDSE-B-2026 の「総人口」のヒストグラムは右に裾を引く明確な右裾分布で、 47 県のほとんどが 100〜300 万人帯に集中し、 1,000 万人を超えるのは東京のみ、 という形になります。 地図上で 等間隔 5 階級の色帯 を使うと、 階級境界が 200 万・400 万・600 万・800 万・1,000 万あたりに切られ、 46 県すべてが最下層に落ちてしまうため、 分位 5 階級(quantile) を選ぶか、 対数変換 してから等間隔にする 2 択になります。

ヒストグラムを見る習慣がないまま地図を作ると、 「都道府県別総人口」を地図にしたら東京だけ濃い色で、 残りは全部薄い色という 「東京 1 点が支配する地図」 ができてしまいます。 一方で対数変換した値を地図化すると、 各都市圏の階層構造(東京 → 大都市圏 → 県庁所在地クラス → 地方)が綺麗な濃淡で表現できます。 つまり、 地図の色階級数は、 ヒストグラムの形を見て決める のが原則です。 ColorBrewer の YlOrRd・OrRd・Reds などのシーケンシャル色帯は 5〜9 階級が推奨で、 ヒストグラムが右裾を引いている場合は 7 階級以上にして上位を細かく刻むか、 対数変換するかの判断が必要になります。
図 3: 箱ひげ図 — 地域区分間の比較
最後に箱ひげ図。 地図上の可視化では「47 都道府県を 1 枚にまとめる」のが基本ですが、 政策議論では 地域ブロック(北海道・東北・関東・中部・近畿・中国・四国・九州沖縄) という単位で比較したい場面が多くあります。 そのときは地図化の前に、 群間の中央値・四分位範囲・外れ値を箱ひげ図で確認しておくと、 「地域差は本当に存在するか」「外れ値はどの県か」が一目で分かります。 SSDSE-B-2026 の「1 人当たり県民所得」を地域ブロックでまとめると、 関東ブロックの中央値が高く、 四国・九州ブロックは中央値がやや低い、 という構造が浮かびます。

箱ひげ図は「群比較における地図の補助」として機能します。 たとえば、 同じ色階級設計で 8 ブロック地図を作ったとき、 関東ブロックだけ濃色が偏るのはなぜか? という疑問に対し、 箱ひげ図が「関東は東京を含むため上方に裾を引いている」「中央値で比較すれば差は小さい」と即答してくれます。 また、 各ブロックの箱の高さ(IQR)が大きく違うと、 「ブロックを 1 色に塗りつぶす地図」が誤読を生む ことも警告してくれます。 地図 + 箱ひげ図のセットは、 「面の地図」が抱える 「群内ばらつきを潰してしまう」弱点 を補う標準的な組み合わせです。
🎮 触って理解する — コロプレス地図の設計を体感する
下の図は SSDSE-B-2026(2023 年度・47 都道府県)の実測値 を、 都道府県を格子状に並べた タイルマップ(簡略日本地図) で塗り分けたコロプレス地図です。 高齢化率は 65 歳以上人口(A1303)÷ 総人口(A1101)× 100 で計算しています。 (1) 階級区分法の切替、 (2) 階級数スライダー、 (3) 実数 vs 率の切替 を操作して、 まったく同じデータでも地図の印象が激変する ことを体感してください。 タイルをタップ(クリック)すると県名と実測値が表示されます。
表示データ:
階級区分法:
階級数:
5 階級
タイルをタップすると県名・実測値がここに表示されます
💡 直感 — 「位置」と「色」の 2 チャンネルで空間パターンを読む
コロプレス地図が伝えるのは 位置(どこ)× 色(どれくらい) の組み合わせです。 棒グラフを 47 本並べても「東北で高い」「太平洋ベルトで低い」という 空間的なまとまり は読めませんが、 地図なら一目です。 上のタイルマップで高齢化率(率モード・分位)を見ると、 秋田 39.06% を頂点に東北・四国・中国山地で高く、 東京 22.75%・沖縄 23.84%・愛知 25.72% など首都圏・大都市圏と沖縄で低い という明瞭な地域パターンが浮かびます。 これは「若年層が進学・就職で大都市へ移動する」という人口移動の空間構造そのものです。
⚠️ よくある落とし穴 — 上の操作で実際に体感する
- ① 実数をそのまま地図化する:「65歳以上人口(実数)」に切り替えると、 東京(320.5 万人)・大阪(242.4 万人)・神奈川(239.0 万人)が最濃になります。 しかしこれは 単に人口が多い県が濃いだけの「人口地図」 です。 高齢化率に直すと東京は 22.75% で全国最下位——順位がほぼ反転します。 実数の地図はどの指標を塗ってもほぼ同じ見た目になる ため、 率・1 人当たり値に正規化するのが原則です。
- ② 階級区分の恣意性:同じ高齢化率でも「等間隔」と「分位」を切り替えると印象が激変します。 実数 + 等間隔では東京 1 都だけが濃く残り 46 道府県がほぼ同色(情報量ゼロ)。 逆に分位は 差がほとんどなくても各階級に必ず同数の県を割り当てる ため、 「差があるように見せてしまう」危険があります。 階級数スライダーを 3 → 9 に動かすと、 境界がまたぐ県の色がころころ変わることも確認できます。 ヒストグラム で分布形を確認し、 分位数 の意味を理解した上で設計するのが正道です。
- ③ 面積の大きい県が目立つ:実際の地形ポリゴン地図では北海道(面積 1 位・人口密度は低い)が視覚的に画面を支配します。 上の図が 全県を同じ大きさのタイル で描いているのはこのバイアスを消すためで、 タイルマップ自体が面積バイアスへの対策の一つです。
🚀 発展 — カルトグラム・タイルマップ・ポイントマップ
カルトグラム(cartogram) は各地域の面積を人口などの値に比例するよう変形した地図で、 面積バイアスを根本的に解消します(東京が巨大に、 北海道が小さく描かれる)。 タイルマップ(tile grid map) は上の図のように全地域を等面積の格子で表す簡略表現で、 選挙報道などで多用されます。 ポイントマップ / バブルマップ は実数(総数)を点の大きさで表す手法で、 「実数は点サイズ・率は色」と役割分担させると 1 枚で 2 変数を正しく伝えられます。 関連ページ: 高齢化率 ・ ヒートマップ ・ 地図投影・ジオコーディング。
🗺 概念マップ
「geo visualization」を中心とした関連概念マップ。
上の概念マップは、 地理可視化を中心に据えて「投影法 (メルカトル / 正距方位)」「表現形式 (コロプレス / ドット / フロー)」「データ前処理 (人口正規化 / 階級分け)」を放射状に配置した。 SSDSE-B-2026 の県別データを地図化するときは、 まず「面積バイアス」を意識し、 必要なら人口比カートグラムや 1 人あたり指標で標準化することで誤読を防げる。
🔗 隣接手法への橋渡し
「地理可視化」は単独で完結する手法ではなく、 隣接領域と連携することで真価を発揮する。
上流の地理座標系 (EPSG)・GeoJSON で空間データを整備し、 並列のコロプレス図・ヒートマップ・カートグラムと表現手法を比較し、 下流の空間統計 (Moran's I)・空間回帰で定量分析に接続する。 地理可視化は探索の入口であり、 必ず空間統計と組み合わせて「目で見た傾向」を検定で裏付ける。
🌳 手法選択フロー
「地理可視化」を実際の課題に当てはめるとき、 状況別に何を選ぶかを 3 段階で判定する。
- データの空間単位は? 行政区 (都道府県・市区町村) → コロプレス図、 点データ → 散布マップ・ヒートマップ、 連続面 → 等高線・3D ボリューム
- 強調したい変数は? 1 変数 → コロプレス、 2 変数 → 二変量カラーマップ・カートグラム、 多変量 → 小倍数 (small multiples)
- 静的か対話的か? 静的レポート → matplotlib・cartopy、 探索・ダッシュボード → folium・kepler.gl・Mapbox
地理可視化は「正確な投影法 + 色覚バリアフリー配色 + 凡例の単位明示」が必須三要素。 メルカトル図法は高緯度を歪めるため面積比較には Equal Area Projection (Robinson・Mollweide) を選ぶ。
🎨 直感を深める — 「地図にデータを重ねる」の三系統
地理可視化の直感は一言で言えば 「表の数字を、 日本列島の形の上に載せ直す」 ことです。 都道府県名でソートした表では 「隣り合う県が似ているか」 は読めませんが、 地図に載せると 空間的なまとまり(西日本/東北/太平洋ベルト) が一瞬で目に入ります。 これは Tobler の第一法則「近いものほど関連が強い」を、 統計検定の前に 目で仮説として掴む ための入口です。 SSDSE-B-2026 は 47 都道府県という 行政区単位で 1 行 の構造なので、 県境ポリゴンと結合するだけで地図化でき、 まさに地図可視化向きのデータです。
データを載せる 3 つの重ね方
| 系統 | 重ね方 | 向いている量 | SSDSE-B での例 |
| コロプレス(塗り分け) | 領域を値で色塗り | 率・密度・比(面積で正規化済みの量) | 高齢化率(65歳以上人口÷総人口)を県ごとに濃淡 |
| バブル(比例記号) | 点の面積で量を表現 | 絶対数(合計・件数) | 総人口を県庁所在地に円で置く(面積バイアスを避けられる) |
| ヒートマップ(密度) | 点群をカーネル密度で連続面に | 生の点イベント(緯度経度付き) | SSDSE-B は県集計値なので直接は不向き、 点データが要る |
重要な使い分けは 「絶対数はバブル、 率はコロプレス」 です。 コロプレスは面積の広い県ほど画面を占有するため、 総人口のような 絶対数を塗ると面積バイアスに直撃 します。 一方バブルは面積と無関係に量を円の大きさで示すので、 絶対数の比較に向きます。 ヒートマップは 1 件=1 点の 生データ(例: 事故発生地点の緯度経度)が必要で、 SSDSE-B のような県集計表からは作れない点に注意します。 詳しくは ヒートマップ ・ カラースケール ・ ジオコード変換 のページも参照してください。
⚠️ 落とし穴を深める(重要)— SSDSE-B-2026 実データで踏み抜く
ここでは既存の「落とし穴」章を 実測値で裏付け ます。 以下の数値はすべて SSDSE-B-2026(cp932, 2 行目=単位行を skip, 2023 年・47 都道府県)から実際に集計したものです。
① 絶対数 vs 率 — 死亡データで真逆の結論が出る
「どの県で人がよく亡くなるか」を 死亡数(絶対) で塗るか 粗死亡率(人口千対) で塗るかで、 地図は正反対になります。 これは正規化忘れがいかに危険かを示す実例です。
| 塗る量 | 上位3県(実測) | 解釈 |
| 死亡数 A4200(絶対) | 東京 137,241 / 大阪 104,964 / 神奈川 98,744 | 単に人口の多い県が並ぶ(人口の写し絵) |
| 粗死亡率 = A4200÷A1101×1000(率) | 秋田 19.2‰ / 青森 17.6‰ / 高知 17.2‰ | 高齢化の進んだ県が浮上 |
決定的なのは 東京です。 死亡数は 全国最多の 137,241 件 なのに、 粗死亡率は 9.7‰ で全国最低。 「絶対数の地図」では東京が最濃、 「率の地図」では東京が最薄と、 同じ県が正反対の色 になります。 分母(人口)を付け忘れた地図は、 事実上「人口分布の地図」を別ラベルで見せているに過ぎません。
② 面積バイアス — 「大きく見える県」に引きずられる
コロプレスは 面積で目立ち方が決まる ため、 人口ではなく面積を無意識に読んでしまいます。 東京は面積が狭いのに 総人口 14,086,000 人(全国最大、 最小の鳥取 537,000 人の約 26 倍) を抱えます。 総人口を塗った地図では、 広大な北海道が視界を支配し、 人口が集中する南関東の小さな区画は視覚的に過小評価されます。 回避策: 絶対数は前述のバブル(比例記号)に切り替える、 または面積を人口で再スケールする カルトグラム(cartogram) を併用します。
③ 階級区分の恣意性 — 総人口は右裾で「東京1点支配」
総人口の分布は 右裾に強く歪んで います(実測: 歪度 2.29、 中央値 1,549,000 人に対し東京 14,086,000 人)。 この分布を 等間隔 5 階級 で切ると、 東京だけが最上位階級に入り 残り 46 県がほぼ最下位階級 に潰れ、 地図の情報量がほぼゼロになります。 階級境界を等間隔/分位/自然分類(Jenks)のどれにするか、 境界値をどこに置くかで 県の色が変わる(階級境界マジック) ため、 境界は必ず 2〜3 通り試して感度分析 し、 分布形(右裾なら log 変換や自然分類)に合わせて選びます。 本ページ上部の 🎮 インタラクティブ・ウィジェットで、 同じデータの階級設計を切り替えて体感できます。
④ MAUP(修正可能領域単位問題)
Modifiable Areal Unit Problem。 集計する単位(都道府県 / 市区町村 / メッシュ)を変えると、 同じ現象でも相関やパターンが変わる という空間データ固有の罠です。 SSDSE-B は都道府県単位ですが、 市区町村単位の SSDSE や地域メッシュに落とすと、 県内のばらつき(東京都内でも都心と多摩の差)が見えて結論が動きます。 「県単位で見えたパターンが、 単位を変えても頑健か」を常に自問します。
⑤ 生態学的誤謬(ecological fallacy)
県という 集団の平均 から 個人 の性質を推論してしまう誤りです。 たとえば「高齢化率の高い秋田県(実測 39.1%、 全国最高。 対して東京は 22.8% で最低、 全国平均 31.6%)」の地図を見て「秋田の人は皆高齢だ」と読むのは誤りで、 県は高齢者と若年者の 混合 です。 地図の色は 領域の集計値 であって個人の値ではない、 という区別を常に保ちます。
⑥ 色覚配慮と ⑦ 投影法の歪み
色覚配慮: 赤緑カラーマップ(レインボー含む)は色覚多様性で区別困難かつ明度順序がないため、 順序データは ColorBrewer の YlOrRd/Blues など 明度が単調に変化する連続配色、 増減など符号を持つ量は 発散配色(RdBu, 青⇔白⇔赤) を選びます(詳細は カラースケール)。 投影法の歪み: Web メルカトルは高緯度で面積が膨張し、 北海道が実面積以上に大きく見えて指標が過大評価されます。 面積比較を伴う地図では等積投影(日本平面直角座標系 / Equal Earth)を選びます。
🚀 発展を深める — 表現手法・階級区分・空間統計
表現手法のカタログ
| 手法 | 要点 | 得意なメッセージ |
| コロプレス(choropleth) | 領域を率で塗り分け | 「どの地域が高い/低いか」 |
| カルトグラム(cartogram) | 面積を変数で歪める | 面積バイアスを消して量を比較 |
| ドット密度(dot density) | 1 ドット=N 件を散布 | 総量と密度を同時に、 県境の連続性錯覚を回避 |
| ヒートマップ(kernel density) | 点群を連続面に | 生イベントの集中度(要・点データ) |
階級区分(classification)の 3 系統
- 等間隔(equal interval): 最小〜最大を N 等分。 分布が一様なら明快だが、 右裾(総人口など)では最上位 1 県が支配。
- 分位(quantile): 各階級に同数の県。 順位は綺麗に出るが、 値の差が小さい群を過度に強調しうる。
- 自然分類(natural breaks / Jenks): 群内分散を最小化する境界を探索。 「東京/大都市圏/県庁所在地/地方」のような階層構造を捉えやすい。
加えて、 平均±σ で切る 標準偏差階級 は「全国平均からの偏差」を語りたい指標(失業率など)に向きます。 選択は ヒストグラムの形と目的(順位/偏差/異常検知)から逆算 します。 上部の 🎮 ウィジェットで等間隔/分位/Jenks を切り替えて違いを確認できます。
正規化(人口あたり)は地図化の前処理の要
前述の死亡データが示す通り、 コロプレスに載せる前に 絶対数を分母付きの率へ変換(1 人あたり・1km²あたり・千人対)するのが原則です。 SSDSE-B では総人口 A1101 を分母に、 死亡率=A4200÷A1101、 高齢化率=A1303÷A1101 のように率を作ってから塗ります。
空間自己相関(Moran's I)— 「目で見た偏り」を検定する
地図で「西日本が高い」と感じても、 それが偶然かどうかは 空間自己相関 で検定します。 Moran's I は −1〜+1 の指標で、 隣接県どうしの値が似ていれば正(クラスタあり)、 交互に高低が並べば負、 ランダムなら 0 付近を取ります。
ローカル版(LISA, Getis-Ord G*)を使えば、 どの県がホットスポット/コールドスポットか を個別に検出できます。 地図で仮説を掴み → Moran's I で全体傾向を検定 → LISA で局所を特定、 という流れが空間統計の王道です。
データ形式と道具立て
- GeoJSON: JSON 形式の地理データ。 Web 親和性が高く folium/Leaflet で扱いやすい。
- シェープファイル(.shp/.shx/.dbf): GIS 古典フォーマット。 QGIS/ArcGIS の標準。 e-Stat・国土数値情報で県境データを配布。
- 座標参照系(CRS): WGS84(EPSG:4326)が世界標準、 日本は JGD2011(EPSG:6668)。 混在すると数百 m ずれるため統一必須。
- Python: GeoPandas(静的)+ folium(対話的)が定番。 空間統計は PySAL(esda.Moran など)。
関連ページ: ジオコード変換(住所→緯度経度・投影法)、 カラースケール(連続・発散配色)、 ヒートマップ、 散布図 ・ 棒グラフ(地図と併載して分布・順位を開示)。 なお カルトグラム・ドット密度・空間自己相関(Moran's I) は本用語集に単独ページがまだ無いため、 上記の解説を参照してください。