1. 境界線データ
Python (および,その他のプログラミング言語)で日本地図を描くためには,何と言ってもまず,都道府県境界線のデータを取得必要がある。
色々選択肢もあるかもしれないが,その中で選ぶならば,国土地理院のウェブサイトから取得できる zip ファイルを使用するのが良いであろう。必要なファイルを前もってダウンロードしておくのが良い。類似記事では直接ファイルに毎回アクセスするような場合もあるが,サーバーへの負担を考えたり,オフラインでの作業も考えると,必要なファイルを一度だけアクセスしてローカルファイルに保存するのがマナーと言うべきであろう。
このファイルには、都道府県とその境界線の情報が含まれている。全国を対象とするファイルも,地域ブロックを対象とするファイルも,各都道府県一つを対象とするファイルも用意されている。ダウンロードする際に,いくつかのアンケートにも誠実に答えよう。そうしなければ,将来的にこのようなありがたいデータが供給され続けるかどうか,危うい状況にもなりかねない。ダイレクトに(毎回)ダウンロードするというのはぜひとも避けてほしい。
2. 必要なパッケージの使用宣言
その次には,プログラミング環境ごとに必要なパッケージをインポートする必要がある。
ここでは、Python を例として取り上げるが,基本的にはどのようなプログラミング環境であろうと,先に上げたダウンロードしたファイルを読み取り,プロットするのに必要なパッケージを用意するということに尽きる。
Python では geopandas
とmatplotlib.pyplot
パッケージを使する。以下のコマンドを使用して、これらのパッケージを使用することを宣言する。まだ,インストールしていない場合はそれぞれのパッケージを pip install する。
# ! pip install geopandas
import geopandas as gpd
import matplotlib.pyplot as plt
ここでは,全国の都道府県データの zip ファイルを対象とする。これがあれば,万能であろう。
ダウンロードした zip ファイルを展開するとできる N03-20210101_GML ディレクトリ中に N03-21_210101.shp というのがある。これが対象とする Shapefile である。ちなみに,Julia や R では同じディレクトリ中の N03-21_210101.geojson を対象とする。
境界線情報を読むのは geopandas の read_file() である。
# Shapefileを読み込む
fp = "N03-20210101_GML/N03-21_210101.shp"
japan = gpd.read_file(fp, encoding="cp932")
japan に読み込む。
japan の型は geopandas.geodataframe.GeoDataFrame
で,先頭5行を見てみると,まあ,データフレームと理解してよいだろう。
データフレームは 6 列からなり,
- N03_001 都道府県名
- N03_002 北海道の場合のデータ
- N03_003 郡市町村データ
- N03_004 市町村名
- N03_007
- geometry 境界線情報
であるが,最重要なのは geometry 列。
type(japan)
geopandas.geodataframe.GeoDataFrame
japan.head(5)
N03_001 | N03_002 | N03_003 | N03_004 | N03_007 | geometry | |
---|---|---|---|---|---|---|
0 | 北海道 | 石狩振興局 | 札幌市 | 中央区 | 01101 | POLYGON ((141.34233 43.06682, 141.34285 43.066... |
1 | 北海道 | 石狩振興局 | 札幌市 | 北区 | 01102 | POLYGON ((141.40839 43.18395, 141.40833 43.183... |
2 | 北海道 | 石狩振興局 | 札幌市 | 東区 | 01103 | POLYGON ((141.44707 43.15616, 141.44694 43.155... |
3 | 北海道 | 石狩振興局 | 札幌市 | 白石区 | 01104 | POLYGON ((141.46244 43.10010, 141.46265 43.100... |
4 | 北海道 | 石狩振興局 | 札幌市 | 豊平区 | 01105 | POLYGON ((141.38463 43.04670, 141.38479 43.046... |
3. 試しに,日本全土の地図を描く。
# 県境の線を描画する
japan.plot(edgecolor='gray', facecolor='none')
# グラフのタイトルを設定する
plt.title('Japan Map')
# 軸を非表示にする
plt.axis('off')
# 地図を表示する
plt.show()
さて本番。色々やってみる
4. ある特定の都道府県のみを指定する場合
df = japan[japan['N03_001'] == '岐阜県']
fig, ax = plt.subplots(figsize=(10, 6))
# 軸を非表示にする
ax.axis('off')
# アスペクト比を 1 にする
ax.set_aspect('equal', 'datalim')
df.plot(ax=ax, edgecolor='black', facecolor='aliceblue', linewidth=0.5)
# 図面を表示する
plt.show()
5. ある特定の複数の都道府県を指定する場合
岐阜県と隣接する岐阜県,長野県,山梨県を同時に描画する。
df = japan[(japan['N03_001'] == '岐阜県') | (japan['N03_001'] == '長野県') | (japan['N03_001'] == '山梨県')]
fig, ax = plt.subplots(figsize=(10, 6))
# 軸を非表示にする
ax.axis('off')
# アスペクト比を 1 にする
ax.set_aspect('equal', 'datalim')
df.plot(ax=ax, edgecolor='black', facecolor='aliceblue', linewidth=0.5)
# 図面を表示する
plt.show()
6. 複数の都道府県を同時に指定し色分けする場合
上と同じく,岐阜,長野,山梨を同時に色分けして描画する。
# サブプロットを作成する
fig, ax = plt.subplots(figsize=(10, 6))
# 軸を非表示にする
ax.axis('off')
# アスペクト比を 1 にする
ax.set_aspect('equal', 'datalim')
# 岐阜県の境界を描画する
df = japan[japan['N03_001'] == '岐阜県']
df.plot(ax=ax, edgecolor='black', facecolor='aliceblue', linewidth=0.5)
# 長野県の境界を描画する
df = japan[japan['N03_001'] == '長野県']
df.plot(ax=ax, edgecolor='black', facecolor='orange', linewidth=0.5)
# 山梨県の境界を描画する
df = japan[japan['N03_001'] == '山梨県']
df.plot(ax=ax, edgecolor='black', facecolor='olive', linewidth=0.5)
# 図面を表示する
plt.show()
7. 前節の応用(区域ごとに色分けする)
中国地方,四国地方をまとめ,それぞれを同じ色で塗り分けて描く。
# サブプロットを作成する
fig, ax = plt.subplots(figsize=(10, 6))
# 軸を非表示にする
ax.axis('off')
# アスペクト比を 1 にする
ax.set_aspect('equal', 'datalim')
for pref in ['山口県', '広島県', '島根県', '鳥取県', '岡山県', '兵庫県']:
df = japan[japan['N03_001'] == pref]
df.plot(ax=ax, edgecolor='black', facecolor='skyblue', linewidth=0.5)
for pref in ['愛媛県', '香川県', '徳島県', '高知県']:
df = japan[japan['N03_001'] == pref]
df.plot(ax=ax, edgecolor='black', facecolor='hotpink', linewidth=0.5)
# 図面を表示する
plt.show()
8. 特定の市町村を描画する
ある都道府県の市町村を指定して描画する。
これだけ見て,そこが私の出身地!とわからない人もいるかも??
df = japan[(japan['N03_001'] == '愛媛県') & (japan['N03_004'] == '伊方町')]
# サブプロットを作成する
fig, ax = plt.subplots(figsize=(10, 6))
# 軸を非表示にする
ax.axis('off')
# アスペクト比を 1 にする
ax.set_aspect('equal', 'datalim')
df.plot(ax=ax, edgecolor='black', facecolor='skyblue', linewidth=0.5)
# 図面を表示する
plt.show()
9. その他の応用
その他も,データフレームから特定のデータを抽出することで,どのような行政区の地図も描くことができる。
Julia を使うメリットは,描画領域についての指示をする必要がないということ。描画領域が収まるように自動的に範囲を設定してくれる(少々...いや,かなり時間がかかるが)。
北海道と東京都と沖縄県の位置関係。間に他の府県が描かれていないと認識している距離感との違いが顕になるやもしれない。
df = japan[(japan['N03_001'] == '北海道') | (japan['N03_001'] == '東京都') | (japan['N03_001'] == '沖縄県')]
fig, ax = plt.subplots(figsize=(10, 6))
# 軸を非表示にする
ax.axis('off')
# アスペクト比を 1 にする
ax.set_aspect('equal', 'datalim')
df.plot(ax=ax, edgecolor='black', facecolor='aliceblue', linewidth=0.5)
# 図面を表示する
plt.show()
10. さらなる応用
基本がわかれば,いろいろなことができる
- 指定した経緯度に文字列を描く
- 行政区画ごとのデータで色分けする
- 行政区画ごとにグラフを表示する(2次元棒グラフなど)
- その他,あれやこれや
誰か,書いて,描いて...