LoginSignup
6
12

More than 5 years have passed since last update.

Pythonで世界地図-23_2(自治体を人口別に色分け)

Last updated at Posted at 2018-08-18

参考

Creating Attractive and Informative Map Visualisations in Python with Basemap
http://www.datadependence.com/2016/06/creating-map-visualisations-in-python/

上記のサイトを半月くらい前に見つけたのですが、内容が理解出来ないので保留していました。
pandas DataFrameが少しわかってきたので、上記の内容を再現できるかやろうとしましたが、別ページでDataFrame「new_areas」を作るようなのですが、うまくいきませんでした。

csvファイルからDataFrameを作成できるようなので、奈良県の市町村別人口で色分けしました。

image.png

ダウンロード

国土数値情報 ダウンロードサービス
http://nlftp.mlit.go.jp/ksj/

で、行政区域「奈良県」のシェイプファイルをダウンロードする。

[{'N03_001': b'\x93\xde\x97\xc7\x8c\xa7', 'N03_002': '', 'N03_003': '', 'N03_004': b'\x93\xde\x97\xc7\x8es', 'N03_007': '29201', 'RINGNUM': 1, 'SHAPENUM': 1}, (奈良市)
{'N03_001': b'\x93\xde\x97\xc7\x8c\xa7', 'N03_002': '', 'N03_003': '', 'N03_004': b'\x91\xe5\x98a\x8d\x82\x93c\x8es', 'N03_007': '29202', 'RINGNUM': 1, 'SHAPENUM': 2}, (大和高田市)

市町村コード一覧表
http://www.tt.rim.or.jp/~ishato/tiri/code/code.htm

総務省 市町村コード一覧表(Excelデータあり)
http://www.soumu.go.jp/denshijiti/code.html

image.png

国土数値情報のシェイプファイルは、'N03_003'=郡または政令市 'N03_004'=市区町村 'N03_007'=行政区域コード
で、市町村の区分けと少し違います。

'N03_007'と市町村コードは同じなのでこれを利用して作業します。
県市町村コードは、Excel/LibreOffice Calcで「=VALUE(B2&C2)」で連結します。
市町村別人口を追加します。これを、Excel/LibreOffice Calc形式で保存します。

image.png

sheet1をコピーして複製を作成します。
一番前のsheetの県市町村コードを「area」に変更します。
少し問題があって、奈良市の上に行を挿入して、「'29200'」と入力します。原因はまだわかりません。エラーの内容は後で説明します。
これで、一度保存し、次にこのsheetを一番上(アクティブ)にした状態でcsvファイルで保存します。

nara.csv

area,支庁市郡,区町村,ふりがな,population_2016
'29200’,,,,
29201,奈良市, ,ならし,358786
29202,大和高田市, ,やまとたかだし,64156
29203,大和郡山市, ,やまとこおりやまし,86466
29204,天理市, ,てんりし,67012
29205,橿原市, ,かしはらし,123640
29206,桜井市, ,さくらいし,56763
29207,五條市, ,ごじょうし,30369
29208,御所市, ,ごせし,26502
29209,生駒市, ,いこまし,118084
29210,香芝市, ,かしばし,78103
29211,葛城市, ,かつらぎし,36720
29212,宇陀市, ,うだし,30415
29320,山辺郡, ,やまべぐん,
29322,山辺郡,山添村,やまぞえむら,3578
29340,生駒郡, ,いこまぐん,
29342,生駒郡,平群町,へぐりちょう,18736
29343,生駒郡,三郷町,さんごうちょう,23573
29344,生駒郡,斑鳩町,いかるがちょう,27267
29345,生駒郡,安堵町,あんどちょう,7415
29360,磯城郡, ,しきぐん,
29361,磯城郡,川西町,かわにしちょう,8435
29362,磯城郡,三宅町,みやけちょう,6813
29363,磯城郡,田原本町,たわらもとちょう,31477
29380,宇陀郡, ,うだぐん,
29385,宇陀郡,曽爾村,そにむら,1508
29386,宇陀郡,御杖村,みつえむら,1697
29400,高市郡, ,たかいちぐん,
29401,高市郡,高取町,たかとりちょう,7087
29402,高市郡,明日香村,あすかむら,5483
29420,北葛城郡, ,きたかつらぎぐん,
29424,北葛城郡,上牧町,かんまきちょう,21903
29425,北葛城郡,王寺町,おうじちょう,23218
29426,北葛城郡,広陵町,こうりょうちょう,33568
29427,北葛城郡,河合町,かわいちょう,17742
29440,吉野郡, ,よしのぐん,
29441,吉野郡,吉野町,よしのちょう,7159
29442,吉野郡,大淀町,おおよどちょう,17729
29443,吉野郡,下市町,しもいちちょう,5500
29444,吉野郡,黒滝村,くろたきむら,637
29446,吉野郡,天川村,てんかわむら,1311
29447,吉野郡,野迫川村,のせがわむら,424
29449,吉野郡,十津川村,とつかわむら,3399
29450,吉野郡,下北山村,しもきたやまむら,858
29451,吉野郡,上北山村,かみきたやまむら,488
29452,吉野郡,川上村,かわかみむら,1267
29453,吉野郡,東吉野村,ひがしよしのむら,1662
#!/usr/bin/python3
# coding: UTF-8

import matplotlib.cm
#import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from matplotlib.patches import Polygon
from matplotlib.collections import PatchCollection

from mpl_toolkits.basemap import Basemap
from matplotlib.colors import Normalize

font = {'family':'IPAGothic'} #日本語Fontを指定

po_nara = pd.read_csv('/home/ty/python/map/japan/data/行政区/N03-180101_29_GML/nara.csv') # .csv読み込み

fig, ax = plt.subplots(figsize=(10,20))

map = Basemap(llcrnrlon=135.5,llcrnrlat=33.7,urcrnrlon=136.3,urcrnrlat=34.9)

map.readshapefile('N03-18_29_180101', 'nara', color='#444444', linewidth=.2) # 奈良県のシェイプファイル読み込み

#奈良県のシェイプファイルからDataFrameを作成
df_poly = pd.DataFrame({
        'shapes': [Polygon(np.array(shape), True) for shape in map.nara],
        'area': [area['N03_007'] for area in map.nara_info]
    })
#上記で作成したDataFrameに人口の入ったcsvの内容をmergeする。
#この段階でエラーがでました。
df_poly = df_poly.merge(po_nara, on='area', how='left')

cmap = plt.get_cmap('Oranges')   
pc = PatchCollection(df_poly.shapes, zorder=2)
norm = Normalize()

pc.set_facecolor(cmap(norm(df_poly['population_2016'].fillna(0).values)))
ax.add_collection(pc)

mapper = matplotlib.cm.ScalarMappable(norm=norm, cmap=cmap)

mapper.set_array(df_poly['population_2016'])
plt.colorbar(mapper, shrink=0.4) #カラーバー

plt.title('平成28年 奈良県市町村別人口', fontsize=15, **font)

plt.show()

エラーの内容
[{'N03_001': b'\x93\xde\x97\xc7\x8c\xa7', 'N03_002': '', 'N03_003': '', 'N03_004': b'\x93\xde\x97\xc7\x8es', 'N03_007': '29201', 'RINGNUM': 1, 'SHAPENUM': 1}, 奈良市

シェイプファイルの'N03_007': '29201'県市町村コードは文字列になっているので、表計算アプリで県市町村コードの前後にシングルコーテーションを追加(文字列)すると、地図が表示されますが、人口のデータが全てNaNになってしまいます。

次にシングルコーテーションを削除すると、
ValueError: You are trying to merge on object and int64 columns. If you wish to proceed you should use pd.concat
ValueError:オブジェクトとint64列をマージしようとしています。 続行したい場合は、pd.concatを使用してください。
エラーがでます。pd.concatでは解決しません。

色々やって試しに一番上の行だけ文字列にしたら動作しました。
知識が不足しているので、原因はわかりません。

日本全国版

総務省で全国の市町村コード(Excelファイル)と
http://www.soumu.go.jp/denshijiti/code.html
全国の市町村の人口
https://uub.jp/rnk/cktv_j.html
を見つけたので全国版を作ろうとしましたが、北海道・東北の市町村コードが'01100'と先頭にゼロがあり、総務省のExcelデータをcsvにした時は、'01100'とゼロが残っているのですが、人口のデータとmergeした時に、ゼロが無くなって(数値?)'1100'しまいます。

スキル不足で解決出来ないので下のコードで、先にマージしたcsvファイルを作成し、不足している市町村コードの先頭の"0"をCalcで挿入しました。

#!/usr/bin/python3
# coding: UTF-8

import pandas as pd


city_code = pd.read_csv('/home/ty/python/map/japan/data/japan_city_code_1.csv') # .csv読み込み
po_japan = pd.read_csv('/home/ty/python/map/japan/data/人口面積.csv') 

city_code1 = pd.merge(city_code, po_japan, on='city', how='left') #2つのcsvをmergeする

city_code1.to_csv( 'japan_city_code_1人口.csv')

注意)
1.
fig, ax = plt.subplots(figsize=(10,20)) #変更前
fig, ax = plt.subplots() #変更後
figsize=(10,20)が指定されているとズーム・パン等のボタンが表示されない
2.
全国の市町村の人口の人口の表では、大阪市・堺市・仙台市・札幌市・横浜市等の各区の人口が記載されずに、市全体の人口が記載されているために大阪市・堺市・仙台市・札幌市・横浜市は人口0人で地図が表示されます。

image.png

6
12
0

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
6
12