2020年12月29日火曜日

[Python] 警視庁の事故データを地図上にプロットしてみた

 今年7月に公開された2019年の交通事故データを使い、日本地図の上にプロットしました。

https://nyoshimura.github.io/JapanTrafficAccident/JapanTrafficAccident.html



  1. 使ったデータ
  2. データの前処理
  3. 地図作成
について書きます。

1. 使ったデータ

警視庁のオープンデータを使いました。


日本語なのでencodingはcp932を使う必要があります。
df = pd.read_csv("./honhyo_2019.csv",encoding='cp932')

2019年以前のデータも含まれていますが、データの90%以上が2019年のものです。










2. データの前処理

元のデータだと緯度経度が度分秒表記かつ整数化のため1000掛けてあるので、通常の10進法緯度経度に変換しました。 (参考: https://www.wingfield.gr.jp/archives/2687)
def dms2dec(latlong_raw):
    var_degree = int(latlong_raw/1e7)
    var_minutes = int(latlong_raw/1e5 - var_degree*100) 
    var_seconds = (latlong_raw/1e3 - var_degree*1e4 - var_minutes*100)
    decimal_latlong = var_degree + var_minutes/60 + var_seconds/3600
    
    return decimal_latlong

3. 地図作成

foliumを使ってopenstreetmap上にプロットしました。

dataframe、 色、地図、凡例名を渡してレイヤー生成する関数を作成してみました。
def addLatLong2map(df_in, color_in, folium_map, legend_name):
    lgd_txt = '<span style="color: {col};">{txt}</span>'
    FeatureGroup_in = folium.FeatureGroup(name= lgd_txt.format( txt= legend_name, col= color_in))
    for index_df in range(len(df_in)):
        folium.CircleMarker([dms2dec(df_in["地点 緯度(北緯)"][index_df]), 
                             dms2dec(df_in["地点 経度(東経)"][index_df])],
                             radius=2,color=color_in,
                             fill=True,fill_opacity=0.9).add_to(FeatureGroup_in)
    folium_map.add_child(FeatureGroup_in)

# create map
folium_map = folium.Map(location=[35.415377, 139.595271], zoom_start=11)

# for loop for lat/long
df_person = df[df["事故類型"]==1].reset_index()
df_nodeath = df_person[df_person['死者数'] == 0].reset_index()
df_death = df_person[df_person['死者数'] > 0].reset_index()

start_time = time.time()

addLatLong2map(df_nodeath,'#ffa500',folium_map, 'pedestrian accident')
print("--- %s seconds for accident loop ---" % (time.time() - start_time))

addLatLong2map(df_death,'#ff0000',folium_map, 'pedestrian death')

# turn on layer control
folium_map.add_child(folium.map.LayerControl())

print("--- %s seconds for all loop ---" % (time.time() - start_time))
    
# save map
folium_map.save('./docs/JapanTrafficAccident.html')

ソースコードはnotebookですがこちら:

Github pagesをホストに使ってhtmlファイルも保存しました:

今後はこの地図上に色々情報付加していく所存。
おしまい。