plotly.expressパッケージのscatter_mapboxで地図に散布図を描いてみる
データアナリティクス事業本部の鈴木です。
今回は、plotly.expressパッケージのscatter_mapbox関数を使って地図上でデータを可視化する方法をご紹介します。
scatter_mapbox関数は、緯度・経度を含むデータフレームを渡すことで、インタラクティブな地図上に散布図を描写できます。
「地図上に散布図を描写できる」と書いてしまうと、なにに使えるんだろう?と感じてしまうかもしれませんが、データを可視化する様々な場面で活躍します。
特に今回は以下の2つのケースを紹介します。
- 値の大きさに意味のあるデータの可視化
- 時系列データの可視化
検証環境
Jupyter Docker Stacksのdatascience-notebookイメージにPlotlyをインストールして検証しました。バージョンなどは以下になります。
- イメージ:jupyter/datascience-notebook:514883dc662a
- Plotly 5.0.0
やってみる
1.値の大きさに意味のあるデータの可視化
まず、値の大きさに意味のあるデータのケースを紹介します。値の大きさに意味のあるとは、例えばある場所での人口や気温などです。
例として、ある年度の都道府県ごとの総人口をscatter_mapbox関数で可視化してみます。 データは以下のようなものです。
code,city,latitude,longitude,population 0,sapporo,43.06415035,141.34676496,1952356 1,aomori,40.82443999,140.74000496,287648 2,morioka,39.70356954,141.15265155,297631 3,sendai,38.2688808,140.87198085,1082159 4,akita,39.718624,140.102386,315814 5,yamagata,38.24055033,140.36335772,253832 (略) 46,naha,26.21244491,127.6809218,319435
このデータのpopulationカラムは2015年度の県庁所在地の総人口で、政府統計の総合窓口(e-Stat)から取得しました。東京都の人口は、23区の人口の和になります。latitudeおよびlongitudeは地理院地図で県庁所在地付近の位置情報を取得しました。
このCSVをpandasでデータフレームとして読み出し、scatter_mapbox関数で可視化してみましょう。
import pandas as pd import plotly.express as px df_city_population = pd.read_csv("./city_population.csv") fig = px.scatter_mapbox( # データフレームおよび緯度・経度の設定 data_frame=df_city_population, lat="latitude", lon="longitude", # ホバー時の表示設定 hover_name="city", hover_data=["population"], # 散布図のマーカーの設定 color="population", size="population", size_max=30, opacity=0.4, # 作図の設定 center={'lat':34.686567, 'lon':135.52000}, zoom=4, height=600, width=800) fig.update_layout(mapbox_style='open-street-map') fig.update_layout(margin={"r": 0, "t": 0, "l": 0, "b": 0}) fig.update_layout(title_text="Population of each cities") fig.show()
実行すると、以下のように県庁所在地の位置に、各都道府県の人口ごとに色と大きさが異なるマーカーを表示することができました。今回は静止画ですが、インタラクティブに操作が可能です。
各引数は以下を指定します。
- data_frame: 処理対象のデータフレーム
- lat: 緯度を表すカラムの名前
- lon: 経度を表すカラムの名前
- color: マーカーの色を決めるカラムの名前
- size: マーカーの大きさを決めるカラムの名前
- size_max: マーカーの大きさの上限
- opacity: マーカーの不透明度
- center: 地図を表示する際の中心の初期値
- zoom: 地図を表示する際の縮尺の初期値
- height:図の高さ
- width:図の幅
また、mapbox_style
でopen-street-mapを指定しました。この値により、使用する地図タイルを選択することができます。
hover_nameとhover_dataは、以下のようにデータ点をホバーした際の表示の制御を行います。
2.時系列データの可視化
次に時系列データケースを紹介します。具体的にはGPSで取得した位置情報を想定しています。
今回は秋葉原駅からぐるっと散歩して、駅の別の入り口に戻ったとして、その軌跡を可視化してみます。
データは以下のようなCSV(trajectory1.csv)を準備しました。
x,y 35.697582,139.772637 35.697579,139.772401 35.697580,139.772191 35.697573,139.771953
データは地理院地図で各地点の緯度・経度を取得しました。このデータとは別にもう一つ別経路のデータ(trajectory2.csv)も作成しました。
以下のコードで可視化してみましょう。
# データの読み込み df_gps1 = pd.read_csv("./trajectory1.csv") df_gps2 = pd.read_csv("./trajectory2.csv") # データごとにラベルを表すカラムを作成した後、1つのデータフレームにまとめる df_gps1["trajectory"] = "trajectory1" df_gps2["trajectory"] = "trajectory2" df_gps = pd.concat([df_gps1, df_gps2]) # データを可視化する fig = px.scatter_mapbox( # データフレームおよび緯度・経度の設定 data_frame=df_gps, lat="x", lon="y", # ホバー時の表示設定 hover_name="trajectory", # 散布図のマーカーの設定 color="trajectory", opacity=1.0, # 作図の設定 center={'lat':35.697582, 'lon':139.772637}, zoom=15, height=600, width=800) fig.update_layout(mapbox_style='open-street-map') fig.update_layout(margin={"r": 0, "t": 0, "l": 0, "b": 0}) fig.update_layout(title_text="GPS trajectories") fig.show()
今回は縮尺に対して相対的にデータ間の距離が開いているので、画像ではちょっと見にくくなってしまっていますが、移動した軌道が可視化されていることが分かります。
※今回のデータだと縮尺を小さくすると軌跡が見やすくなりました。
OpenStreetMapに可視化することで、データ系列と地理情報の関係性もよく分かるようになります。インタラクティブな地図なので、拡大・縮小やスライドすることも可能です。
最後に
plotly.expressパッケージのscatter_mapboxを使ったデータの可視化例を紹介しました。
特にGPSで取得した位置情報の軌跡ような時系列データを可視化する際に、とても簡単に、分かりやすいインタラクティブプロットが描写できるのでとても気に入っています。
plotly.expressパッケージにはscatter_mapboxのほかにも地理的なデータの可視化に使える関数があるので、ぜひ利用してみてください。