Pythonでつくば市の交通事故件数のヒートマップを作る
こんにちは、つくばに住む研究者です。
今回はタイトルの通り、つくば市の交通事故件数のヒートマップを作ります。利用するデータは国土交通省が公開している市の境界線の図形ファイル、同じく同省の公開する幹線道路の図形ファイルに加えて、警察庁の公開する交通事故統計情報のオープンデータです。
今回はつくば市について作成しますが、全国についてデータは公開されていますので、お住まいに任意の市区町村について作成できます。
まずは3つのデータを地図上に書き込んでいきます。いつものようにデータを読み込み、市の外形を描きます。
from google.colab import drive
import pandas as pd
import matplotlib.pyplot as plt
import geopandas as gpd
import folium
import japanize_matplotlib
japanize_matplotlib.japanize()
drive.mount('/content/drive')
fig = Figure(width=1100, height=1100)
map = folium.Map(location=[36.1, 140.1] ,zoom_start=11.5,tiles='cartodbpositron',zoomSnap=0.25)
area_style_function = lambda x: {'color' : 'blue','opacity' : 0.50,'weight' : 1,}
fig.add_child(map)
gdf_area = gpd.read_file('市の領域を示す.shpデータの場所',encoding='shift-jis')
folium.GeoJson(gdf_area[gdf_area['N03_004']=='つくば市'],style_function = area_style_function).add_to(map)
map
これに道路を書き加えます。
gdf_roads = gpd.read_file('道路の形状データの.shpファイルの場所', encoding='Shift-JIS')
street_style_function = lambda x: {'color' : 'black','opacity' : 0.30,'weight' : 1, 'dashArray':5}
folium.GeoJson(gdf_road['geometry'].unary_union, style_function = street_style_function).add_to(map)
map
これに、交通事故データのヒートマップを重ねます。
まずは交通事故データを前処理します。警察庁のオープンデータは座標が日本測地系で与えられているため、これを世界測地系に直します。また、茨城県のつくば市のデータだけを取り出します。
df = pd.read_csv('警察庁の事故データの場所',encoding='shift-jis')
df = df[df['都道府県コード']==40]#茨城
df = df[df['警察署等コード']==131]#つくば
def dms2deg(df, col):
df2 = df.copy()
df2['d'], df2['t'] = df2[col].divmod(10000000)
df2['m'], df2['s'] = df2['t'].divmod(100000)
converted = df['d'] + (df['m'] / 60.0) + (df['s'] / 1000.0 / 3600.0 )
return converted
df['lat'] = 0
df['lon'] = 0
df['lat'] = dms2deg(df, '地点 緯度(北緯)')
df['lon'] = dms2deg(df, '地点 経度(東経)')
次にヒートマップを作成するためのデータを整理します。ヒートマップの作成にはfoliumのHeatmap pluginを使います。データ形式は[緯度、経度]または[緯度、経度、数字]のいずれかです。前者の場合はレコードの数をもとに、後者の場合は数字をもとにヒートマップの色が決定されます。
ys = [ys for ys in df['lat']]
xs = [xs for xs in df['lon']]
zipped = zip(ys, xs)
heat_data = [list(i) for i in list(zipped)]
from folium import plugins
folium.plugins.HeatMap(
data=heat_data,
radius=25,
blur=25,
max_opacity=1
).add_to(map)
map
だいぶそれらしくなりました。最後に、件数をマーカーで表示するようにします。これにはMarkerCluster pluginを使います。
from folium.plugins import MarkerCluster
marker_cluster = MarkerCluster().add_to(map)
for i in heat_data:
folium.Circle(location=[i[0],i[1]],weight=0,color='#FFFFFF', radius=200,fill_opacity=0.1,fill=True,fill_color='#00FF77',label='1').add_to(marker_cluster)
map
ヒートマップやマーカーは地図の縮尺に併せてインタラクティブに動作します。中心部を拡大してみましょう。
おそらく交通量が多いであろう、つくば駅の付近で最も事故が多いようです。駅付近は歩行者や自転車も多いことも原因となっているかもしれません。警察庁のオープンデータでは、事故の車両の種類や時間帯などの属性もあるため、より詳細な分析が可能ですが、今回はこのあたりにしておこうと思います。
それでは。