つくば市の人口偏在についてPythonでグラフにしてみる
こんにちは、つくばに住む研究者です。
前回はつくば市の各地区の駅からの距離と平均年齢の関係を調べました。
今回は前回作成したデータを利用して、人口のヒートマップを作ろうと思います。併せて、駅の周辺の人口密集度についても見ていきます。
さて、前回は国勢調査をもとにした人口データと国土地理院による各地区の座標データを紐付けしました。つまり、どの地区(座標)にどのくらいの人口が住んでいるかが既にわかっています。これをfoliumのheatmap pluginを使えばヒートマップの作成はすぐに出来てしまいます。
データフレームを作成するまでの手順は前回の記事と同様なので省略します。heatmap pluginに与えるデータ形式は[緯度, 経度, 数値]とする必要があるため、まずはデータフレームからそれぞれのリストを作成し、zipで先述の形式と合わせます。
ys = [ys for ys in gdf['Y_CODE']]
xs = [xs for xs in gdf['X_CODE']]
ps = [ps for ps in gdf['JINKO']]
zipped = zip(ys, xs, ps)
heat_data = [list(i) for i in list(zipped)]
foliumで地図上に描写します。
import folium
from folium import plugins
from shapely.ops import cascaded_union
fig = Figure(width=700, height=1000)
map = folium.Map(location=[36.1, 140.1] ,zoom_start=11.5,tiles='cartodbdark_matter',zoomSnap=0.25)
folium.plugins.HeatMap(
data=heat_data,
radius=25,
blur=25
).add_to(map)
gdf_area = gpd.read_file(つくば市の形状の.shpファイルへのパス)
area_style_function = lambda x: {'color' : 'blue','opacity' : 0.70,'weight' : 1,}
folium.GeoJson(gdf_area[gdf_area['N03_004']=='つくば市'],style_function = area_style_function).add_to(map)
fig.add_child(map)
予想どおりですが、つくば市の人口はTX駅周辺に集中して分布しているようです。どのくらいの人口集中なのか、駅からの距離に応じた累積居住者数をプロットしてみることにします。
現在のデータは常総線や常磐線も考慮した距離となっているため、これをつくば市内のTXの4駅(みどりの、万博記念公園、研究学園、つくば)までの距離に直すために、駅の座標をもつデータフレームについて、常磐新線を指定して抽出します。
df_st2 = df_st2[df_st2['N02_003']=='常磐新線']
grs80 = pyproj.Geod(ellps='GRS80')
gdf['station_name'] = ''
for j, rows in gdf.iterrows():
dists = []
for i,row in df_st2.iterrows():
_,_, dist = grs80.inv(gdf.iloc[j]['geometry'].centroid.x, gdf.iloc[j]['geometry'].centroid.y,
df_st.iloc[i]['geometry'].centroid.x, df_st.iloc[i]['geometry'].centroid.y)
dists.append(dist)
gdf.loc[j, 'station_name'] = df_st2['N02_005'].iloc[np.argmin(np.array(dists))]
# print(min(dists))
gdf.loc[j,'dist_from_station'] = min(dists)/1000
地図上で様子を確認すると以下のようになりました。2.5kmごとに色を変えるようにしています。
駅までの距離を正しく割り当てられていることを確認しましたので、距離に応じた累積居住人口をプロットします。ついでに、該当地区を含めた累積の居住地区面積もプロットします。まずは図に与えるデータを整理します。
p1 = [gdf[gdf['dist_from_station']<=i]['JINKO'].sum() for i in v]
gdf['AREA'] = gdf['AREA']/1000000
p3 = [gdf[gdf['dist_from_station']<=i]['AREA'].sum() for i in v]
p2 = []
for i in range(0,len(p1)):
if i == 0:
p2.append(0)
else:
p2.append(p1[i] - p1[i-1])
プロットします。
fig, ax1 = plt.subplots(figsize = (6,6),dpi=100)
ax2 = ax1.twinx()
ax1.grid(True)
ax2.grid(False)
ax1.plot(v,p1,'ob-',label='累計居住者数 (人)')
ax2.plot(v,p3,'og-',label='累計面積'+" [$km^{-2}$]")
ax1.set_ylabel('累計居住者数 (人)')
ax2.set_ylabel('累計面積'+" [$km^{-2}$]")
ax1.set_xlabel('駅からの距離 [km]')
ax2.spines['left'].set_color('blue')
ax2.spines['right'].set_color('green')
handler1, label1 = ax1.get_legend_handles_labels()
handler2, label2 = ax2.get_legend_handles_labels()
ax1.legend(handler1 + handler2, label1 + label2, loc='lower right', borderaxespad=2)
plt.title('居住地の駅からの距離と累計居住者数および累計地区面積')
最後に前の図と対応するように背景に色を塗っておきます。ついでに全体からの割合のわかるように横線もいれておきましょう。
どうやら人口の40%が地図中の黄色の地区(市面積の約18%)に、70%が黄緑の地区(同約45%)までに住んでいるようです。
それでは。