Lesson 23

L23 DID地区境界 14件 統合分析 — 広島県の都市部・非都市部の地理構造

都市計画DID人口集中地区14市町統合国勢調査都市核コンパクトシティgeopandasDoBoX
所要 30〜40 分 / 想定レベル: 中級 (GIS + 都市地理学) / データ: DoBoX DID地区境界 14件 (#1468,1471,1473,1476,1479,1482,1485,1487,1490,1493,1495,1500,1502,1505)

データ取得手順

このスクリプトは初回実行時にデータを自動取得します(DoBoX からの直接ダウンロード)。

IDデータセット名
#222dataset #222
#333dataset #333
#444dataset #444
#600雪崩危険箇所情報_北広島町
#666dataset #666
#888都市計画区域情報_区域データ_安芸高田市_行政区域
#1468都市計画区域情報_DID地区境界データ_広島市_2020
#1471都市計画区域情報_DID地区境界データ_呉市_2020
#1473都市計画区域情報_DID地区境界データ_竹原市_2020
#1476都市計画区域情報_DID地区境界データ_三原市_2020
#1479都市計画区域情報_DID地区境界データ_尾道市_2020
#1482都市計画区域情報_DID地区境界データ_福山市_2020
#1485都市計画区域情報_DID地区境界データ_府中市_2020
#1487都市計画区域情報_DID地区境界データ_三次市_2020
#1490都市計画区域情報_DID地区境界データ_大竹市_2020
#1493都市計画区域情報_DID地区境界データ_東広島市_2020
#1495都市計画区域情報_DID地区境界データ_廿日市市_2020
#1500都市計画区域情報_DID地区境界データ_府中町_2020
#1502都市計画区域情報_DID地区境界データ_海田町_2020
#1505都市計画区域情報_DID地区境界データ_坂町_2020

実行コマンド:

cd "2026 DoBoX 教材"
python -X utf8 lessons/L23_did_boundary.py

DoBoX のオープンデータは申請不要・商用/非商用とも利用可。 data/extras/.gitignore 対象(約 57 GB のキャッシュ)。 スクリプト実行で自動再生成されます。

1. 学習目標と問い

本記事は、広島県インフラマネジメント基盤 DoBoX が公開する 「都市計画区域情報_DID地区境界データ」シリーズ 14 件 (#1468, #1471, #1482, #1493, #1495, #1479, #1476, #1473, #1485, #1490, #1487, #1500, #1502, #1505) を縦結合し、R2 国勢調査ベースで広島県内 14 DID 指定市町の 人口集中地区 (DID) 計 48 ポリゴンから、 広島県の都市部の地理構造 ── 全県 DID 配置・市町別 DID 個数と規模・人口密度・ DID 面積占有率・居住誘導区域 (LIP) との関係 ── を分析する研究記事である。 DID は「都市そのもの」を定義する国勢調査の中心概念であり、 DID の地理は都市計画・コンパクトシティ政策の出発点である。 全 20 市町中 6 市町は DID 無指定 ── そのコントラストも研究対象とする。

研究の問い (RQ): 広島県内 14 DID 指定市町の DID は、 面積・人口・密度・連続性・市町間配分の観点でどのような地理構造を持ち、 県全域の都市部 vs 非都市部の地理はどう描けるか? DID 指定の有無は何を物語るのか?

仮説 H1〜H6

独自用語の定義 (本レッスン内のみ)

到達点

  1. 14 ZIP の DID GeoJSON を 1 個の GeoDataFrame (48 polygon × 9 列 + 派生 5 列) に縦結合できる。 内 1 件 (三次市 ds=1487) は GeoJSON リソースが他市町データを誤配布していたため、 Shapefile リソースから geojson に変換する手順も学ぶ。
  2. 48 polygon から、市町単位の DID 個数・面積・人口・密度・占有率の 集計を groupby で実装する。
  3. DID polygon を geopandas.plot(column=...)主題図 (choropleth)化し、人口密度の地理分布を可視化する。
  4. 14 市町 small multiples で「市町ごとの DID 配置パターン」を一目で比較。 「核がいくつあって、市域のどこに位置するか」を学ぶ。
  5. 居住誘導区域 (LIP) との空間的オーバーレイで、 コンパクトシティ政策の「現在 (DID) → 将来 (LIP)」の関係を実証する。
  6. DID 無指定 6 市町と DID 指定 14 市町を対比して、 「都市指定の有無の地理的意味」を理解する。

本記事のスコープ宣言

本記事はDID 地区境界 14 件のみを主データとする研究記事である。 L19 居住誘導区域 8 件は「現在の都市核 vs 将来の集約核」のコントラストを 描く参考データとして使用するが、L19 主導の居住誘導分析記事と合体させない (要件 I 違反の水増し回避)。 L22 性別年齢別人口の町丁単位データとのクロス分析 (DID 内 vs 外の高齢化率)発展課題に留める。 14 DID 市町と 6 DID 無指定市町のコントラスト (人口・面積・地理タイプ) は 本データ + 行政区域で完結するため分析に含める

2. 使用データ

DID 地区境界 14 件はそれぞれ 1 市町分の DID polygon GeoJSON (MultiPolygon) を ZIP で配布している。列構造は 14 件で 100% 一致 (9 列)

14 dataset_id 一覧 (DID 指定市町)

dataset_id市町市町タイプDoBoX DID数DID人口DID面積(ha)CITY_CD
#1468広島市政令市DoBoX181,039,09313,220101,102,103,104,105,106,107,108
#1471呉市中核市DoBoX5142,7022,771202
#1482福山市中核市DoBoX6264,6315,990207
#1493東広島市施行時特例市DoBoX467,4641,165212
#1495廿日市市DoBoX381,1781,503213
#1479尾道市DoBoX348,1211,142205
#1476三原市DoBoX144,6851,039204
#1473竹原市DoBoX16,084221203
#1485府中市DoBoX118,628568208
#1490大竹市DoBoX221,871793211
#1487三次市DoBoX18,793220209
#1500府中町DoBoX150,893578302
#1502海田町DoBoX127,732481304
#1505坂町DoBoX19,263265309

合計: 48 DID polygon / DID 人口 1,831,138 人 / DID 面積 29,956 ha = 299.6 km² (R2 国勢調査ベース)。広島県全域人口約 278 万人に対し、 DID 集中率は 65.9% ─ 県民の約 2/3 が DID 内に居住している。

DID 無指定 6 市町 (参考)

市町タイプ地理タイプ 面積 km²人口 (千人)密度 (人/km²)
庄原市中山間1246.53326
安芸高田市中山間537.82750
江田島市離島100.722218
熊野町広島近郊町33.723682
北広島町中山間646.21726
世羅町中山間278.21554

DID 無指定の 6 市町は「中山間」「離島」「広島近郊町」の 3 タイプ。 人口密度は最大の熊野町 (683/km²) でも DID 認定線の 4,000 人/km² の 1/6 程度。

列構造の詳細 (9 列)

列名意味
TOKEI_CDint32 統計区分コード。本データ全件 1 (定数)
CITY_CDint32 市区町村コード。広島市は 8 区を 101-108 で分割するため、 広島市内の DID は 8 通りの CITY_CD を持つ
KUIKI_CDint32 区域コード。本データ全件 1 (DID 区域識別、定数)。 三次市の Shapefile 経由データのみ 3 となるが、 意味解釈に大きな影響なし
ZU_NOobject DID 地区番号 ('a','b','c'... アルファベット)。 市町内で連番。広島市は a-r の 18 文字、 福山市は a-f
TOCHI_Aint32 DID 面積 (ha)。単位はヘクタール。 geom.area / 10,000 とほぼ完全に一致 (実測 0.998-1.000 倍)
JINKOU_Sint32 DID 人口。R2 国勢調査ベース。 DID 認定基準により最小 5,000 人以上が原則
BIKOUobject 備考。本データでは全件 None
RITTEKI_CDint32 立地コード (1 / 2 の 2 値、仕様書未公開のため参考扱い)
geometryMultiPolygon DID ポリゴン境界。EPSG:6671 (JGD2011 平面直角第III系)。 本記事の主役データ。市内に飛び地のある DID は MultiPolygon が複数 part
データ品質ノート: ds=1487 (三次市) は GeoJSON リソースが 府中市 (ds=1485) のデータを誤配布 していた (sha256 ハッシュ完全一致で検出)。 本記事では Shapefile リソース (rid=94876) から geojson に変換し直して使用。 fetch スクリプト経由で自動修復される。 このような「公開データの実例的な品質問題」は教材として正面から扱う。

3. ダウンロード (再現用データ・中間データ・図・スクリプト)

本記事の再現性を担保するため、HTML 1 枚から 生データ・中間 CSV・図 PNG・再現 Python を直リンクで取得できる。

(1) 生データ ZIP (DoBoX 直)

14 件の ZIP は前項の表からそれぞれ DoBoX へリンク。 あるいは一括取得スクリプト:

cd "2026 DoBoX 教材"
py -X utf8 data\extras\L23_did_boundary\fetch_did_boundary.py

合計サイズ約 1.7 MB。監査時に取得済の 3 市町 (広島市・呉市・福山市) は data/extras/_urban_planning_audit/ から自動コピー、 残り 11 市町は DoBoX から HTTP 取得 (約 10 秒)。 三次市 (ds=1487) のみ Shapefile から GeoJSON への変換手順を含む。

(2) 中間 CSV (本スクリプトの出力)

(3) 図 PNG (本記事掲載 9 枚)

(4) 再現用 Python スクリプト

実行は cd "2026 DoBoX 教材"; py -X utf8 lessons\L23_did_boundary.py。 14 ZIP がローカルにあれば 1 分以内で全図 + CSV 再生成 (要件 S 準拠)。

4. 分析1: 14 DID GeoJSON 統合 + 派生指標

狙い

14 ZIP の DID GeoJSON を 1 個の GeoDataFrame (48 polygon × 9 列 + 派生 5 列) に統合し、後段の市町別集計・主題図・LIP オーバーレイの基盤データを作る。行政区域 21 件 (DID 14 + 無指定 6 + 広島県全域 1) を背景レイヤーとして同時に読み込む。

手法

直感: ZIP を読む → 列を共通 9 列に揃える → 縦結合 → CRS 変換 → 派生指標 (面積/密度/コンパクトネス/飛び地数) を計算 → 行政区域 dissolve で背景レイヤー作成。

大筋 (5 ステップ)

  1. 14 市町について load_geojson_zip() で GeoDataFrame を読む
  2. 共通 9 列に正規化 (本データは追加列無し、L22 の Shape_Area/Shape_Leng のような付加列も無い)
  3. 派生列 src_city / src_dsid / ctype を付与
  4. pd.concat で縦結合 → 48 行 1 個の GeoDataFrame
  5. 派生指標 5 つを計算: geom_area_km2, density_per_km2, compactness (Polsby-Popper), n_parts (飛び地数), src_city
  6. 行政区域 21 件を読込 (DID 指定 14 + 無指定 6 + 広島県全域)、dissolve(by='city') で市町単位の境界を作成

前提と限界: 14 件の DID データは追加列が全く無く、L22 の庄原市のような付加列ケースは無い。三次市 (ds=1487) の GeoJSON リソースは府中市 (ds=1485) のデータを誤配布していた事例があり、fetch スクリプトで Shapefile から geojson 変換する追加処理を入れた。コンパクトネス指標 (Polsby-Popper) は境界線の凹凸に敏感で、実距離で精密に面積測定された MultiPolygon でも 0.3-0.5 程度の値が出る (完全な円形を期待しない)。

実装

L23_did_boundary.py 行 1120–1253

 1
 2
 3
 4
 5
 6
 7
 8
 9
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
DATA_DIR  = ROOT / "data" / "extras" / "L23_did_boundary"
ADMIN_DIR = ROOT / "data" / "extras" / "L15_admin_zones"
TARGET_CRS = "EPSG:6671"

# 14 件は 9 列 100% 共通
COMMON_COLS_9 = ["TOKEI_CD", "CITY_CD", "KUIKI_CD", "ZU_NO",
                 "TOCHI_A", "JINKOU_S", "BIKOU", "RITTEKI_CD", "geometry"]

frames = []
for dsid, name, _adm, ctype, _lip in CITY_DEFS:
    z = DATA_DIR / f"did_{dsid}_{name}.zip"
    g = load_geojson_zip(z)             # ZIP 内の単一 .geojson 読込
    g = g[COMMON_COLS_9].copy()         # 列正規化 (9 列)
    g["src_city"] = name
    g["src_dsid"] = dsid
    g["ctype"] = ctype
    frames.append(g)

did = gpd.GeoDataFrame(pd.concat(frames, ignore_index=True),
                       geometry="geometry", crs=frames[0].crs)
did = did.to_crs(TARGET_CRS)

# 派生列
did["geom_area_m2"]    = did.geometry.area
did["geom_area_ha"]    = did["geom_area_m2"] / 1e4
did["geom_area_km2"]   = did["geom_area_m2"] / 1e6
did["density_per_km2"] = did["JINKOU_S"] / did["geom_area_km2"].clip(lower=1e-6)
# Polsby-Popper コンパクトネス (1=円, 0=線)
did["compactness"]     = (4 * np.pi * did["geom_area_m2"]
                          / did.geometry.length.clip(lower=1) ** 2)
# MultiPolygon の part 数 (飛び地数)
did["n_parts"]         = did.geometry.apply(
    lambda g: len(list(g.geoms)) if g.geom_type == "MultiPolygon" else 1)

入出力 Before/After (具体例: 1 DID polygon が派生指標に変換される)

段階このデータで何が起きるか1 行の値の例 (広島市 ZU_NO=a)
入力JINKOU_S DID 内人口 (国勢調査の生データ) 203,202 (人)
入力TOCHI_A DID 面積 (ha 単位) 2,507 (ha) = 25.07 km²
入力geometry DID 境界 MultiPolygon (m 単位、EPSG:6671) POLYGON ((...300 頂点...))
派生geom_area_km2 = geom.area / 1e6 geometry 由来の正確な面積 (km²) 25.064 km² (TOCHI_A の 0.999 倍 ─ ほぼ一致)
派生density_per_km2 = JINKOU_S / geom_area_km2 DID 内の人口密度 (人/km²) 8,107 人/km² (DID 認定線 4,000 の 2 倍)
派生compactness = 4πA/P² 形状の円形度 (1=円, 0=線) 0.382 (細長い都市軸を反映)
派生n_parts MultiPolygon の構成 polygon 数 (飛び地数) 3 (川や山で分断された 3 つの部分)

このように、9 列の生データから 密度・形状・連続性の派生指標を導出することで、 DID の地理構造を多角的に評価できる。 特に density と compactness の組み合わせは 「コンパクトな高密度都市核」と「線的な集落」を区別する強力な指標。

結果

14 ZIP のうち、14 件すべてが共通 9 列で読み込み成功。統合後の did GeoDataFrame は 48 polygon × 14 列(9 共通 + src_city + src_dsid + ctype + 派生 5)。処理時間は 20.1 秒で要件 S を満たす。

表 1 — 14 DID 市町読込ログ

市町タイプDID数DID人口DID面積(ha)CITY_CD群ZU_NO
広島市政令市181,039,09313,220101,102,103,104,105,106,107,108a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r
呉市中核市5142,7022,771202a,b,c,d,e
福山市中核市6264,6315,990207a,b,c,d,e,f
東広島市施行時特例市467,4641,165212a,b,c,d
廿日市市381,1781,503213a,b,c
尾道市348,1211,142205c,b,a
三原市144,6851,039204a
竹原市16,084221203a
府中市118,628568208a
大竹市221,871793211a,b
三次市18,793220209a
府中町150,893578302a
海田町127,732481304a
坂町19,263265309a

この表から読み取れること: 広島市 18 DIDが圧倒的に多く、CITY_CD={101..108} の 8 区にまたがる。次が福山市 6, 呉市 5, 東広島市 4, 尾道市 3, 廿日市市 3 と続く。8 市町は DID が 1 つのみで、ZU_NO は 'a' 単独。単核都市 vs 多核都市の構造の違いが ZU_NO のリストから直視できる。広島市の a-r という 18 文字は、地理的にも「都市の核が 18 ある」(8 区 × 平均 2-3 DID) ことを示している。

5. 分析2: 県全域 DID 主題図 + DID 指定 vs 無指定 (H1, H6)

狙い

広島県内の DID 全 48 polygon の地理的配置を 1 枚で見せる。「都市部はどこで、非都市部はどこか」を地図で直接視覚化することは、DID 概念の本質を理解する最短経路。DID 指定 14 市町 vs 無指定 6 市町を色分けで対比する 2 枚目で、「都市指定の有無」の地理的意味も同時に伝える。

手法

(a) 県全域 DID 主題図: 全 21 市町 (= 14 DID + 6 無指定 + 広島県全域)の行政区域を背景にし、geopandas.plot(facecolor=ctype_color, alpha=0.78) で DID polygon を市町タイプ色 (政令市赤・中核市紫・施行時特例市紫・市青・町緑) で描画。凡例とラベル ('広島市 18DID/103 万人' のような注記) で要約する。

(b) DID 指定 vs 無指定 マップ: 14 DID 市町をオレンジ、6 無指定市町を緑で塗り、DID polygon を赤で重ねる。「無指定市町には DID 赤が乗らない」を一目で見せる。

実装

L23_did_boundary.py 行 1275–1310

 1
 2
 3
 4
 5
 6
 7
 8
 9
1284
1285
1286
1287
1288
1289
1290
1291
1292
# (a) 県全域 DID 主題図
fig, ax = plt.subplots(figsize=(13, 9))
admin_diss.plot(ax=ax, facecolor="#f5f5f5", edgecolor="#888", linewidth=0.4)
admin_did = admin_diss[admin_diss["did_status"] == "DID指定"]
admin_did.plot(ax=ax, facecolor="#fafff0", edgecolor="#444", linewidth=0.5)
for ct, col in CTYPE_COLOR.items():
    sub = did[did["ctype"] == ct]
    sub.plot(ax=ax, facecolor=col, alpha=0.78, edgecolor="#222",
             linewidth=0.4, label=f"{ct} DID ({len(sub)} 件)")

# (b) DID 指定 vs 無指定
fig, ax = plt.subplots(figsize=(13, 9))
admin_diss[admin_diss["did_status"] == "DID指定"].plot(
    ax=ax, facecolor="#fee0b6", edgecolor="#444", linewidth=0.6)
admin_diss[admin_diss["did_status"] == "DID無指定"].plot(
    ax=ax, facecolor="#cfe9d8", edgecolor="#444", linewidth=0.6)
did.plot(ax=ax, facecolor="#cf222e", alpha=0.85, edgecolor="#600",
         linewidth=0.5)

図 1 — 県全域 DID 主題図 (48 polygon, 市町タイプ色)

なぜこの図か: テーブルや棒グラフでは「DID が県のどこに、どう連なっているか」が分からない。地図 1 枚で「沿岸部 (広島・呉・福山) に DID が集中、中山間 (北・東部) に DID が無い」という県全体の地理構造を一気に伝える。

広島県 DID 地区境界 全 48 polygon (R2国勢調査)
広島県 DID 地区境界 全 48 polygon (R2国勢調査)

この図から読み取れること

図 2 — DID 指定 vs 無指定 14 市町 vs 6 市町

なぜこの図か: 「都市指定の地理境界」を一目で見せる。DID 無指定 6 市町は『中山間 + 離島 + 広島近郊町』の 3 タイプに明確に分類される ─ これは地図でないと伝わらない (テーブルでは抽象的)。

DID 指定 14 市町 (オレンジ) vs DID 無指定 6 市町 (緑)
DID 指定 14 市町 (オレンジ) vs DID 無指定 6 市町 (緑)

この図から読み取れること

表 2 — 14 DID 指定市町 vs 6 DID 無指定市町 サマリ

区分市町数合計面積 km²合計人口 千人DID 数DID 人口 千人DID 集中率
DID 指定 14144,8702,625481,83169.8%
DID 無指定 662,843137000%
計 (20 市町)207,7132,762481,83166.3%

この表から読み取れること: DID 指定 14 市町は面積では県の 63.1%だが、人口では 95.0%を占める ─ DID 無指定 6 市町は面積で 36.9%あるのに人口は 5.0%。県全域の DID 集中率は 65.9% ─ 県民の約 2/3 が DID 内に居住。「14 市町の都市部に県人口の大半が集中する」のが広島県の地理構造。

6. 分析3: 市町別 small multiples + 個数/集中率/占有率 (H2, H4)

狙い

14 市町の DID 配置パターンを 14 panels small multiples で並列比較する。市町ごとの「都市の核がいくつあって、市域のどこに位置するか」を一目で見せ、単核都市 (n=1) と多核都市 (n≥2) の質的違いを地図で示す。

手法

plt.subplots(3, 5) で 15 panel を作り、14 市町の DID をそれぞれ市町タイプ色で描画。最後の 1 panel は DID 無指定 6 市町の参考表示。各 panel のタイトルに DID 数 / 人口 / 面積を併記。panel ごとに bbox は市域に揃える (= 各市町の市域全体を表示) ので市域に対する DID の相対的な大きさが伝わる。

実装

L23_did_boundary.py 行 530–557

 1
 2
 3
 4
 5
 6
 7
 8
 9
539
540
541
542
543
fig, axes = plt.subplots(3, 5, figsize=(18, 12))
for ax_, (dsid, name, _adm, ctype, _lip) in zip(axes.flat, CITY_DEFS):
    cnt = admin_diss[admin_diss["city"] == name]
    cnt.plot(ax=ax_, facecolor="#f5f5f5", edgecolor="#888")
    sub_did = did[did["src_city"] == name]
    sub_did.plot(ax=ax_, facecolor=CTYPE_COLOR[ctype], alpha=0.85)
    cnt.boundary.plot(ax=ax_, color="#333")
    p, a, n = sub_did["JINKOU_S"].sum(), sub_did["TOCHI_A"].sum()/100, len(sub_did)
    ax_.set_title(f"{name} ({ctype}) {n}DID / {p:,}人 / {a:.1f}km²")

# 個数 bar
order_n = city_agg.sort_values("n_did", ascending=True)
ax.barh(order_n["city"], order_n["n_did"],
        color=[CTYPE_COLOR[ct] for ct in order_n["ctype"]])

図 3 — 市町別 DID 配置 14 panels small multiples

なぜこの図か: 1 枚の県全域図では、市町ごとの「DID パターンの質的違い」が分からない。14 panels で並列比較すると、「広島市の 18 DID 帯」と「府中町の 1 DID で町域ほぼ全部」が同じスケールで対比でき、都市規模と DID 配置の関係が直感的に伝わる。

市町別 DID 配置 small multiples (14 DID panel + 6 DID 無指定 panel)
市町別 DID 配置 small multiples (14 DID panel + 6 DID 無指定 panel)

この図から読み取れること

図 4 — 市町別 DID 個数 + DID 集中率 + DID 面積占有率

なぜこの図か: 市町を 3 つの異なる指標 ─ 「DID がいくつあるか」「市民の何割が DID に住むか」「市域の何割が DID か」 ─ で並べると、大都市と小都市の構造の違いが立体的に見える。1 つの指標だけでは見えない『都市らしさ』の多軸性を伝える。

市町別 DID 個数 / 集中率 / 面積占有率 (3 連 panel)
市町別 DID 個数 / 集中率 / 面積占有率 (3 連 panel)

この図から読み取れること

表 3 — 14 DID 市町 集計表 (個数降順)

市町タイプDID数DID人口DID面積 km²密度 人/km²集中率占有率
広島市政令市181,039,093132.27,86087.4%14.58%
福山市中核市6264,63159.94,41857.7%11.56%
呉市中核市5142,70227.75,15068.0%7.85%
東広島市施行時特例市467,46411.75,79134.1%1.83%
廿日市市381,17815.05,40169.4%3.07%
尾道市348,12111.44,21437.0%4.01%
大竹市221,8717.92,75884.1%10.08%
三原市144,68510.44,30149.6%2.20%
竹原市16,0842.22,75325.4%1.87%
府中市118,6285.73,28050.3%2.90%
三次市18,7932.23,99717.6%0.28%
府中町150,8935.88,80596.0%55.58%
海田町127,7324.85,76592.4%34.86%
坂町19,2632.63,49577.2%16.88%

この表から読み取れること: DID 数の最大は広島市 18、最小は 1 が 8 市町n=1 の市町でも DID 集中率は 30-100% と幅広い ─ 単核都市の中にも『町ぐるみ型 (府中町)』と『中心部だけ型 (三次市)』の質的差がある。密度は府中町 8,805 ~ 竹原市 2,753 人/km² で3.20 倍の格差 ─ 同じ DID でも市町間で密度が大きく違う。占有率上位は小規模町 (府中町・海田町・坂町) で 17-56%、政令市・中核市は 8-15%、中山間市は 1-2% という3 階層構造

7. 分析4: DID 人口密度 主題図 + top/bot 分析 (H3)

狙い

DID polygon 単位で人口密度の地理を可視化する。DID 認定線 (4,000 人/km²) を基準に、各 DID がどの程度上回っているかを色で示し、「都市らしさの強度」を地理的に把握する。

手法

geopandas.plot(column='density_per_km2', cmap='YlOrRd') でpolygon を密度で塗り分け。vmin=2000, vmax=12000 にクリップ(DID 認定線 4,000 を中央に置く)。凡例 colorbar に水平線で 4,000 ラインを描画して、認定基準を視覚化する。

実装

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 人口密度 (geometry の正確な面積から計算)
did["density_per_km2"] = did["JINKOU_S"] / (did.geometry.area / 1e6).clip(lower=1e-6)

# choropleth (DID polygon 単位)
fig, ax = plt.subplots(figsize=(13, 9))
admin_diss.plot(ax=ax, facecolor="#f5f5f5")
did_plot = did.copy()
did_plot["dens_clip"] = did_plot["density_per_km2"].clip(2000, 12000)
did_plot.plot(ax=ax, column="dens_clip", cmap="YlOrRd",
              vmin=2000, vmax=12000, alpha=0.85)
sm = plt.cm.ScalarMappable(cmap="YlOrRd", norm=Normalize(2000, 12000))
cb = plt.colorbar(sm, ax=ax)
cb.set_label("DID 人口密度 (人/km²)\n4000 が DID 認定線")
cb.ax.axhline(4000, color="black", linewidth=1.2)  # 4000 ラインを明示

図 5 — DID 単位 人口密度 主題図

なぜこの図か: 「同じ DID でも密度は均一ではない」という事実を地図で見せる。YlOrRd (黄→橙→赤) は連続値の段階を視覚的に強調するパレットで、高密度 DID と低密度 DID を直感的に区別できる。

DID polygon 単位 人口密度 主題図 (n=48 polygon)
DID polygon 単位 人口密度 主題図 (n=48 polygon)

この図から読み取れること

表 4 — DID 人口密度 top 10 polygon

順位市町ZU_NOCITY_CD人口面積 ha密度 人/km²コンパクト飛び地
1広島市a101142,6991316108410.191
2広島市e1056,93464107790.421
3広島市o1076,9997691520.141
4府中町a30250,89357888020.191
5広島市p10896,392114983900.101
6広島市b102104,525127482050.041
7広島市f105203,202250781050.031
8広島市d104178,803231477270.071
9広島市c103144,689193674750.121
10広島市q1088,99612273480.161

この表から読み取れること: 密度トップは 広島市 a 10841 人/km²。全国の高密度都市 (東京都心 ~15,000) と同水準ではないが、県内ではトップクラス。上位 10 件はすべて広島市 + 府中町 + 海田町 + 福山市の中心 DID。高密度 DID はコンパクトネス指標も比較的高め (0.4 前後) で、『密で円形に近い都市核』がトップに入る。

表 5 — DID 人口密度 bot 10 polygon

順位市町ZU_NOCITY_CD人口面積 ha密度 人/km²コンパクト飛び地
1大竹市a21116,26760127050.151
2竹原市a2036,08422127560.071
3廿日市市c2136,30021928710.101
4大竹市b2115,60419229150.081
5府中市a20818,62856832790.101
6東広島市c2126,23718134390.201
7坂町a3099,26326534910.071
8尾道市b20513,07436835490.111
9尾道市c2057,26819637030.081
10三次市a2098,79322040050.111

この表から読み取れること: 下位は密度 2,500-3,500 人/km² で、DID 認定線 4,000 をやや下回る polygon もある。これは『連担すれば部分的に 4,000 を下回ってもよい』という DID 定義の柔軟性を示す。下位 10 件には中山間 (竹原・三次・大竹) の DID が多く、飛び地数 (n_parts) が複数のものが目立つ ─ 小集落をつないで連担とみなす『細長い DID』のパターン。

8. 分析5: 面積×人口 log-log + コンパクトネス×密度 散布

狙い

DID 面積と人口の関係を log-log 散布で示し、「都市の規模分布」「密度の都市タイプ依存」を可視化する。コンパクトネス指数 × 密度の散布図で、形状と密度の関係も同時に確認する。

手法

(a) log-log 散布: x軸 = TOCHI_A (ha)、y軸 = JINKOU_S (人)、両対数。傾き 1 の直線は密度一定を意味し、4,000人/km² の DID 認定線y = 40·x で重ね描き (x が ha なので 4,000人/km² = 40 人/ha)。市町タイプで色分けする。

(b) コンパクトネス × 密度 散布: x軸 = density_per_km2、y軸 = compactness (Polsby-Popper)。「密度が高い + コンパクト」の DID は理想的な都市核「密度が低い + 細長」の DID は線形集落

実装

L23_did_boundary.py 行 1618–1647

 1
 2
 3
 4
 5
 6
 7
 8
 9
1627
1628
1629
1630
1631
1632
# 面積×人口 log-log + 認定線
fig, ax = plt.subplots(figsize=(11, 9))
for ct, col in CTYPE_COLOR.items():
    sub = did[did["ctype"] == ct]
    ax.scatter(sub["TOCHI_A"], sub["JINKOU_S"], c=col, label=ct)
xs = np.array([20, 5000])
ax.plot(xs, xs * 40, ls="--", label="DID 認定線 (4,000人/km²)")  # ha 単位
ax.set_xscale("log"); ax.set_yscale("log")

# コンパクトネス × 密度
fig, ax = plt.subplots(figsize=(11, 9))
for ct, col in CTYPE_COLOR.items():
    sub = did[did["ctype"] == ct]
    ax.scatter(sub["density_per_km2"], sub["compactness"], c=col, label=ct)
ax.axvline(4000, ls="--", color="black", label="DID 認定線")

図 6 — DID 面積 × DID 人口 (log-log + 認定線)

なぜこの図か: 面積と人口は4 桁にまたがる広いレンジ(20 ha ~ 5,000 ha, 5,000 人 ~ 200,000 人)、log-log でないと小さい DID が原点付近で潰れて見えなくなる。認定線を重ねることで、「DID 内の密度ばらつき」が直感的に伝わる。

DID 面積 × DID 人口 (log-log 散布)
DID 面積 × DID 人口 (log-log 散布)

この図から読み取れること

図 7 — コンパクトネス × 人口密度 散布

なぜこの図か: 密度と形状はそれぞれ独立した『都市らしさ』の側面。両者の散布を見ると『コンパクトな高密度都市核』vs『線的な低密度集落』の二極構造があるかを定量的に判定できる。

DID コンパクトネス × 人口密度 散布
DID コンパクトネス × 人口密度 散布

この図から読み取れること

表 6 — DID 人口 top 10 polygon

順位市町ZU_NOCITY_CD人口面積 ha密度 人/km²コンパクト飛び地
1福山市a207208,342473444010.041
2広島市f105203,202250781050.031
3広島市d104178,803231477270.071
4広島市c103144,689193674750.121
5広島市a101142,6991316108410.191
6広島市b102104,525127482050.041
7広島市p10896,392114983900.101
8呉市a20264,536132648660.021
9廿日市市a21355,57197956780.061
10呉市b20252,428101351740.051

この表から読み取れること: 人口トップは 福山市 a 208,342 人 (広島市 8 区中の最大 DID)。上位 10 件中 広島市が 5+ 件を占め、福山市・呉市・東広島市などが続く。「人口集中地区」の名にふさわしく、トップ DID は地方中核都市の主要駅・繁華街周辺に対応する。top10 の人口合計は1,251,187 人で、これだけで全 DID 人口 (1,831,138) の 68.3% を占める ─ 『DID 内のさらなる集中』が見える。

9. 分析6: 市町総人口 vs DID 人口 + DID 無 6 市町分析 (H6)

狙い

市町の総人口と DID 人口の関係を散布で示し、「都市らしさが市町規模にどう依存するか」を可視化する。DID 無指定 6 市町を×印で同じ散布に重ね、「人口があっても DID にならない閾値」を観察する。

手法

x軸 = 市総人口、y軸 = DID 人口、市町タイプ色で散布。「100% 集中ライン」(y=x) と「50% 集中ライン」(y=0.5x) を破線で重ね、市町ごとの DID 集中率を視覚的に判定。DID 無指定 6 市町は y=0 の x 印として配置し、「同じ人口規模でも DID 化する/しない」の境界を観察する。

実装

L23_did_boundary.py 行 1722–1749

 1
 2
 3
 4
 5
 6
 7
 8
 9
1731
1732
1733
1734
1735
# 14 DID 市町: 散布
for ct, col in CTYPE_COLOR.items():
    sub = city_agg[city_agg["ctype"] == ct]
    ax.scatter(sub["city_pop_k"]*1000, sub["did_pop"], c=col, s=160)

# 6 DID 無指定市町: x=人口, y=0 の x 印
for _, r in no_did_agg.iterrows():
    ax.scatter(r["city_pop_k"]*1000, 0, marker="x", c="#666", s=120)

# 100% / 50% ライン
xs = np.linspace(10000, 1500000, 50)
ax.plot(xs, xs, ls="--", label="100% 集中")
ax.plot(xs, xs*0.5, ls=":", label="50% 集中")
ax.set_xscale("log"); ax.set_yscale("symlog", linthresh=10000)

図 8 — 市町総人口 vs DID 人口 (DID 無 6 市町併置)

なぜこの図か: 市町別 14 件のデータを 1 軸ずつ(個数・占有率・集中率) で見せた前節 fig 06 を、『総人口を横軸にとった散布図』に統合する。DID 無 6 市町を混ぜると「人口があっても DID にならない例外」の存在が一目で分かる ─ これは1次元のテーブルでは伝わらない。

市町総人口 vs DID 人口 (DID 無 6 市町は ×印で y=0 に配置)
市町総人口 vs DID 人口 (DID 無 6 市町は ×印で y=0 に配置)

この図から読み取れること

表 7 — DID 無指定 6 市町 詳細

市町タイプ地理タイプ面積 km²人口 千人密度 人/km²
庄原市中山間1246.53326
安芸高田市中山間537.82750
江田島市離島100.722218
熊野町広島近郊町33.723682
北広島町中山間646.21726
世羅町中山間278.21554

この表から読み取れること: DID 無指定 6 市町は『中山間 4 + 離島 1 + 広島近郊町 1』のタイプ分布。全市町の人口密度は最大の熊野町 683 人/km² が最高 ─ DID 認定線 4,000 の 1/6 程度。『市町平均密度が低い + 集落が分散 → DID 化しない』のパターン。江田島市は離島で集落が小島ごとに分散、中山間 4 市町 (庄原・北広島・安芸高田・世羅) は山間に集落が散在、熊野町は広島市近郊だが筆形地形で集落が線状に細長く伸びるため認定基準を満たさない。

10. 分析7: LIP (居住誘導 L19) との空間オーバーレイ (H5)

狙い

居住誘導区域 (LIP, L19 で扱った 8 件) と DID の空間的オーバーレイを計算する。LIP は『将来この区域に人口を集約する』と自治体が定めた区域、DID は『現在の人口集中地区』。両者の重なり率 LIP_in_DID で「現在の都市核 → 将来の集約核」の連続性を検証する。

手法

LIP は L19 で取得済の 8 件 (広島市・呉市・竹原市・三原市・福山市・府中市・東広島市・廿日市市) を読込。各市町についてgeopandas.overlay(did_city, lip_city, how='intersection') で重なり面積を計算。LIP_in_DID = 重なり / LIP 全体(LIP の何割が DID 内か)、DID_covered_by_LIP = 重なり / DID 全体 (DID の何割が LIP 化されたか) を出す。前者が『将来計画の現実性』、後者が『縮約意図の強さ』を表す。

実装

L23_did_boundary.py 行 1808–1843

 1
 2
 3
 4
 5
 6
 7
 8
 9
1817
1818
1819
1820
1821
1822
1823
1824
1825
# 8 LIP 策定市町を読込
lip = gpd.GeoDataFrame(pd.concat([
    load_geojson_zip(LIP_DIR / f"jukyo_{lip_dsid}_{name}.zip").assign(src_city=name)
    for lip_dsid, name in LIP_DEFS]))

# 市町別 dissolve
did_by_city = did.dissolve(by="src_city", as_index=False)
lip_by_city = lip.dissolve(by="src_city", as_index=False)

# 8 市町ごとに intersection
for _dsid, name, _adm, _ct, lip_dsid in CITY_DEFS:
    if lip_dsid == 0: continue
    inter = gpd.overlay(did_by_city[did_by_city["src_city"]==name],
                        lip_by_city[lip_by_city["src_city"]==name],
                        how="intersection")
    inter_km2 = inter.geometry.area.sum() / 1e6
    overlap_rows.append({"city": name, "lip_in_did_pct":
                          inter_km2 / lip_area * 100, ...})

図 9 — LIP ∩ DID 8 panels (8 LIP 策定市町)

なぜこの図か: 数値表 (LIP_in_DID = 80% など) では実感がわかない。赤 (DID) と緑 (LIP) を重ね描きすることで、「LIP は DID にどれだけ似ているか/縮約しているか」が視覚的に伝わる。8 panels で並列表示し、市町ごとの政策スタイルの違いも見せる。

LIP (居住誘導 L19) ∩ DID (本記事) — 8 LIP 策定市町
LIP (居住誘導 L19) ∩ DID (本記事) — 8 LIP 策定市町

この図から読み取れること

表 8 — DID ∩ LIP 重ね合わせ (8 LIP 策定市町)

市町DID 面積 km²LIP 面積 km²重なり km²LIP_in_DIDDID_covered_by_LIP
広島市132.20145.70112.5777.3%85.1%
呉市27.7116.6312.8177.0%46.2%
福山市59.9073.5043.2458.8%72.2%
東広島市11.6524.529.0036.7%77.3%
廿日市市15.0320.3012.8763.4%85.6%
三原市10.398.215.8871.6%56.7%
竹原市2.213.291.3942.3%63.0%
府中市5.685.564.7986.3%84.4%

この表から読み取れること: LIP_in_DID 中央値は 67.5% ─ つまり『LIP の半分前後が DID 内』。これは「LIP = DID の継承」という素朴な仮説を支持する一方、50% という数字は「LIP は DID をそのまま使うのではなく、少し変形して将来の集約核を作っている」ことも示す。市町別では広島市・福山市の LIP が DID をほぼ覆う一方、廿日市市 (63%) はLIP がかなり外れている ─ 山地部の DID を LIP から除外している。「LIP は将来計画、DID は現状実態」の差分が政策スタイルの違いを浮かび上がらせる。

11. 仮説検証と考察

分析 1〜7 の結果から、仮説 H1〜H6 を改めて検証する。

仮説仮説内容検証結果判定
H1広島市が DID 件数の 30% 超 + DID 人口の 50% 超を占める広島市 DID 数 18/48=37.5%, DID 人口 1,039,093/1,831,138=56.7%支持
H2DID 個数 1 つの市町が 5 件以上 + 3+ DID の市町も 3 件以上単核 DID (n=1) 7 市町、多核 DID (n>=3) 6 市町支持
H3市町間 DID 平均人口密度の最大/最小 ≥ 3 倍max=府中町 8805人/km², min=竹原市 2753人/km², ratio=3.20x支持
H4市町の DID 面積占有率 5% 未満が 8 市町以上 + 30% 超が 2 市町以上占有率 <5% は 7 市町、>=30% は 2 市町部分支持
H5LIP の 50% 以上が DID 内 (LIP ⊆ DID)LIP_in_DID >= 50% は 6/8 市町, 中央値 67.5%支持
H6DID 無 6 市町のうち 5+ 件が人口 3 万以下人口 ≤3 万: 5/6 件支持

総括

本記事の主要発見 5 点

  1. 『広島市が県の都市部の中核』を定量化: 県 DID 数の 37.5%、DID 人口の 56.7% が広島市 8 区。中核市 (呉・福山) を合わせても県 DID 人口の 79.0%。政令市・中核市 3 つで県都市部の 8 割超
  2. 『単核都市 8 vs 多核都市 6』の二極構造: 単核都市は「町ぐるみ DID」(府中町など) と「中心部のみ DID」(三次市など) の 2 サブタイプに分かれる。多核都市は政令市 (広島市) と合併由来 (東広島市) と地形分断 (呉市・尾道市) の混在。
  3. 『町ぐるみ DID』の小規模町: 府中町・海田町・坂町は DID 占有率 17-56%、DID 集中率 77-96% で町域のほぼ全部が都市。「町=町ぐるみ DID」という地理現象は、政令市 (広島市) のベッドタウン化が町という行政単位を都市に変えた結果。
  4. LIP_in_DID 中央値 67.5% = LIP は DID を継承: 立地適正化計画の居住誘導区域は、現在の DID をほぼ受け継いでいるが、市町ごとに縮約・拡張のスタンスが違う。呉市・三原市は『将来縮約』東広島市は『将来拡張』の対照がオーバーレイで定量化された。
  5. DID 無指定 6 市町の 3 タイプ: 中山間 (庄原・北広島・安芸高田・世羅)・離島 (江田島)・近郊集落分散 (熊野町)。同じ人口規模 (2-3 万) でも DID 化する/しないは集約度。竹原市 (人口 24,000) と熊野町 (23,000) の DID 有無の対比はその典型。

12. 発展課題

本記事で得られた結果から導かれる新たな問いと、 それを検証するための具体的な発展手順を 3 つ提示する。

発展課題 1: DID 内 vs 外の高齢化率と人口ピラミッド比較 (L22 連携)

結果 X: 本記事で県内 DID 48 polygon の地理が定量化された。 L22 では町丁単位の高齢化率・年少率・性比が計算済。 両者を空間結合すれば『DID 内町丁 vs DID 外町丁』の人口構造比較が可能。

新仮説 Y: DID 内町丁の高齢化率は DID 外町丁より10%pt 以上低く、 年少率は 5%pt 以上高い。『人口集中地区は構造的に若い』。 中山間市町 (三次市・三原市) でも DID 内 (中心市街地) と DID 外 (集落) で 構造が分裂し、市町平均では捉えきれない局地差が見える。

課題 Z: geopandas.sjoin(pop, did, how='left', predicate='intersects') で町丁に DID 内/外フラグを付与し、4 群構成 (年少/生産/前期高齢/後期高齢) を DID 内外でクロス比較。20 市町 small multiples で DID 内 vs 外の人口ピラミッドを並列。 『DID 内ほど若い』が市町間で一貫するかを検証。

発展課題 2: DID 経年変化 (H27 vs R2) — 都市の縮小と拡大

結果 X: 本記事は R2 (2020) DID の 1 時点スナップショット。 人口減少社会では、5 年前 (H27) との差分が政策上重要。

新仮説 Y: 中山間都市 (三次市・三原市) の DID は5 年で面積が縮小し、 中心部だけに後退している (郊外集落が DID 認定基準を割り込む)。 逆に東広島市の DID は面積が拡大し (大学・産業発展)、 広島市は緩やかに北側へ拡張 (郊外住宅地化)。

課題 Z: 政府統計 e-Stat から H27 国勢調査 DID 境界 GIS を取得 → ZU_NO で対応付けして R2 と空間差分計算 → fig: H27 DID 境界 (薄青) + R2 DID 境界 (赤) 重ね描き → ΔDID 面積 / ΔDID 人口の市町ランキング。 『DID の縮小と拡大の地理』が見える。 R7 (2025) のデータが出れば 10 年スパン 3 点比較。

発展課題 3: DID 認定基準の検証 — 4,000 人/km² 連担条件

結果 X: 本記事の DID 単位密度 (= JINKOU_S/geometry面積) は下位 polygon で 2,500-3,500 と DID 認定線 (4,000) を下回るものが見つかった。 これは『連担すれば部分的に下回ってもよい』という DID 定義の柔軟性を示すが、 具体的にどの程度緩和されているか定量的には不明。

新仮説 Y: 国勢調査メッシュ (1/4 地域メッシュ ≈ 500m) を使えば、 DID polygon 内のメッシュ単位密度を計算でき、 『DID polygon 全体の平均密度は 4,000 を下回ることもあるが、 構成メッシュの 70%+ は 4,000 超』のような連担条件が定量できる。

課題 Z: e-Stat から R2 国勢調査 1/4 地域メッシュ 人口を取得 → DID polygon と空間結合 → polygon 内メッシュ別密度ヒストグラム → 「polygon 平均は低くても構成メッシュの大半は 4,000 超」を確認。 DID 定義を実データで再現する作業。 『国勢調査の中心概念をデータから自分で再構築する』体験となる。