LoginSignup
16
18

More than 3 years have passed since last update.

【Python】市区町村レベルの塗り分け地図プロット

Last updated at Posted at 2019-12-03

この記事の目的

Pythonで以下の様な, 市区町村レベルの塗り分け地図を描く
都道府県レベルならこちら

plot08.png

当初は, geopandas + geoplotで行おうと思っていたが, Google Colabでgeoplotがうまくインストールできなかったため, geoplotを諦めいろいろ行錯誤して, 最もシンプルであろう方法にたどり着いた.
基本的にgeopandasが追加でインストールできればOK.

ちなみに塗り分けの色は, 今回は乱数の値を元にしているので, 適宜データを変えてもらいたい.

ページの最後にコード一覧があります.

解説

色付きの地図を作成するために, geopandas というライブラリを用いる

pip install geopandas

その他ライブラリの準備

import numpy as np
import geopandas as gpd
import random
import matplotlib.colors
import matplotlib.pyplot as plt

市区町村の形(ポリゴン)のデータを「国土数値情報 ダウンロードサービス」からダウンロードして適当な編集ソフト(QGISなど)で前処理を行う.

前処理で必ず行うこととしては, 以下のように, 同じ市区町村なのに複数のポリゴンからなるデータを1つにまとめなければならない. また, 必要に応じて, ポリゴンの簡素化なども行う.

plot07.jpg
QGISを使う場合はここなどを参考にしてもらいたい.

前処理が済んだデータをgeojson形式でエクスポートして, これをgeopandasで読み込む
ファイルのディレクトリは適宜変えてもらいたい.

filename = "/content/drive/My Drive/Colab Notebooks/pref47.geojson"
df = gpd.read_file(filename, encoding='SHIFT-JIS')

また, 塗り分けに使うデータをここでgeopandas形式のデータフレームに追加する.
使い方は, pandasと同様なのでわかりやすい.
今回は簡単のために, ランダムな値を用いているが, ここに人口や賃金などのデータを入れることを想定している.

df["target"] = [random.random() for i in range(df.shape[0])]

市区町村ごとのデータから, 塗り分けを行う色を決定する関数を定義しておく

def colors_scale(arr):
    n_min = min(arr)
    n_max = max(arr)
    cmap = plt.cm.rainbow
    norm = matplotlib.colors.Normalize(vmin=n_min, vmax=n_max)

    arr = [cmap(norm(r)) for r in arr]
    return arr, cmap, norm

最後に地図のプロット
pandasと同様の書き方で, 興味のあるデータだけを選択してmini_dfとしている.
df.plotを行うときにcolor=で色情報のリストを渡すのがポイント

mini_df = df[df["N03_001"].isin(["愛媛県", "徳島県", "香川県", "高知県"])]

target_color, cmap, norm = colors_scale(mini_df["target"])

mini_df.plot(color=target_color, figsize=(10,6))
sm = plt.cm.ScalarMappable(cmap=cmap, norm=norm)
plt.colorbar(sm)
plt.show()

以上!

コード一覧

pip install geopandas
import numpy as np
import geopandas as gpd
import random
import matplotlib.colors
import matplotlib.pyplot as plt

filename = "/content/drive/My Drive/Colab Notebooks/pref47.geojson"
df = gpd.read_file(filename, encoding='SHIFT-JIS')

df["target"] = [random.random() for i in range(df.shape[0])]

def colors_scale(arr):
    n_min = min(arr)
    n_max = max(arr)
    cmap = plt.cm.rainbow
    norm = matplotlib.colors.Normalize(vmin=n_min, vmax=n_max)

    arr = [cmap(norm(r)) for r in arr]
    return arr, cmap, norm


mini_df = df[df["N03_001"].isin(["愛媛県", "徳島県", "香川県", "高知県"])]

target_color, cmap, norm = colors_scale(mini_df["target"])

mini_df.plot(color=target_color, figsize=(10,6))
sm = plt.cm.ScalarMappable(cmap=cmap, norm=norm)
plt.colorbar(sm)
plt.show()

参考

国土数値情報 ダウンロードサービス
09.いくつかの地物をまとめて一つの地物にする
pythonを用いたshapefileやgeojsonの読込および描画

16
18
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
18