はじめに
12月といえばadvent calendar、そして忘年会。
忘年会に参加する人が色んな場所に散らばってると
場所を決めるのが結構苦労しますよね
参加する人の職場(最寄り駅)の座標から重心取って
そこらへんを開催場所にすれば公平になるな、
わかりやすく地図にプロットして可視化したいな、と思い
実際にやってみた、という内容です。
googleマップでできるかな?と思いましたが、
各駅調べて座標取って計算する、とかが大変そうでした。
(もしかしたらうまいやり方があるのかもしれません。。。)
簡単に地図に座標プロットして、計算もできるものないかなと色々調べた結果
foliumを活用しました。
folium
foliumはleaflet.jsというマップライブラリを使い、
簡単にデータを可視化できるpythonライブラリです。
インストールはconda(もしくはpip)にて簡単に行えます。
私はcondaで実行しました。
conda install folium
*foliumについてはこちらの@nakakenashiさんのqiitaの記事を参考にさせていただきました。
Folium: Pythonでデータを地図上に可視化
やってみました
以下の方針で実施しました。
1. 駅名から座標へ変換する
2. 座標の平均をとる = 開催場所とする
3. 各駅/開催場所をプロットして可視化する
1.駅名から座標へ変換する
駅名、座標を保持したデータないかと探したところ、
色々と見つかりましたがその中でも
駅データ.jp を使用しました。
無料で会員登録を行い駅データの最新版を取得。
station20171109free.csvという名前のファイルがダウンロードできます。
中を見てみるとこのようになっていました。
駅名(station_name),緯度(lat),経度(lon)を使います。
*駅データ探しはこちらの@kouさんのqiitaの記事を参考にさせていただきました。
駅とか路線のマスターデータの入手方法
2. 座標の平均をとる = 開催場所とする
csvデータをpandasで読み込み
対象の駅データを抽出。
緯度/経度の平均を求めます。
import pandas as pd
df = pd.read_csv('station20171109free.csv')[['station_name','lat','lon']]
# 駅データには複数路線の駅データがあるため駅名ごとに1つに絞る
df = df.drop_duplicates(['station_name'])
# 参加者の最寄り駅
base_station = ['秋葉原','厚木','市川','横浜','大岡山','高田馬場','池尻大橋']
for index, row in df.iterrows():
if row['station_name'] not in base_station:
df = df.drop(index)
# 平均をとる
average_pos = df.mean()
3. 各駅/開催場所をプロットして可視化する
あとは取得した各駅と計算した中心の座標を地図にプロットします。
ようやくfoliumを使います。
import folium
# 中心座標付近の地図を作成
m = folium.Map(location=[average_pos['lat'], average_pos['lon']], zoom_start=11)
# 各駅をプロット(色は青)
df.apply(lambda row:
folium.Marker(
location=[row['lat'], row['lon']],
popup=row['station_name'],
icon=folium.Icon(color='blue')
).add_to(m), axis=1)
# 中心座標をプロット(色は赤)
folium.Marker(
location=[average_pos['lat'], average_pos['lon']],
popup='集合場所',
icon=folium.Icon(color='red')
).add_to(m)
中心は、、、
都立大学駅付近ですね
最後に
foliumを使うと本当に簡単に地図にデータを表示できたな、と思います。
Map,Marker以外にも色々あるので使ってみてまた記事を書ければいいなと思います。
.
.
ちなみに結局忘年会の場所は渋谷になりました。(近からずとも遠からず?)