Posted at
PythonDay 16

Folium: Pythonでデータを地図上に可視化

More than 1 year has passed since last update.

Foliumはデータを地図上に可視化するライブラリです。

JavaScriptのLeafletという

対話的な地図への処理をサポートするライブラリがあり

Foliumはこのライブラリをパースし、Pythonで使えるようにしたものといえます。


環境構築

公式ページで対応バージョンなどがつかめませんでしたが

pypiでカテゴリを見た感じだと、2系でも3系でも動きそうです。

ある程度新しいPythonの環境で以下のコマンドを実行。'Easiest'です。


foliumのインストール

$ pip install folium


環境を汚したくない場合はvenvなどで事前に分離してください。

私は使い捨てのコンテナを立てました。

FROM python:3.5.2-alpine

RUN pip install folium


コンテナの起動

# カレントディレクトリのDockerfileでfoliumイメージを作成

docker build -t folium .

# foliumイメージからコンテナを起動
docker run -it -v /home/nanakenashi/workspace:/workspace folium /bin/sh


Foliumから吐き出すhtmlファイルを参照するため

カレントディレクトリ(workspace)をコンテナ内にマウントしています。


試してみる

QuickStartにお世話になります。

まずはPythonの対話シェルを起動し、foliumを読み込みます。


下準備

$ python

Python 3.5.2 (default, Nov 17 2016, 22:46:45)
[GCC 5.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>> import folium


地図を作ってみる

座標とズームレベルを片手にMapオブジェクトを作成し、名前を付けて保存します。

ズームレベルは数値が大きいほどアップになっていきます。


地図の作成と保存

>>> map1 = folium.Map(location=[-30.159215, 138.955078], zoom_start=4)

>>> map1.save('/workspace/map1.html')

保存したhtmlファイルをブラウザで開いてみます。

map_html.png

locationに指定した座標は中心じゃなかったんだろうかと

中心からズレたオーストラリアを見て思いましたが、先へ進みます。


マーカーを置いてみる


マーカーの追加

>>> map2 = folium.Map(location=[-30.159215, 138.955078], zoom_start=4)

>>> folium.Marker([-31.253218, 146.921099], popup='New South Wales').add_to(map2)
<folium.map.Marker object at 0x7fc1c73bd048>
>>> map2.save('/workspace/map2.html')

保存したmap2.htmlを開いてみます。

map2_html.png

マーカーが出現しました。

ちなみにクリックするとpopupで指定した文字列が表示されます。

marker.png


可視化っぽいことをしてみる

Quickstartの中だけでも様々な可視化オプションが使用されていますが

今回は円形のマーカーに着目して何かを出してみます。

まずは試しに。


円形のマーカーを表示

>>> map3 = folium.Map(location=[-30.159215, 138.955078], zoom_start=4)                                                                             

>>> folium.CircleMarker([-31.253218, 146.921099],
... radius=100000,
... popup='New South Wales',
... color='#3186cc',
... fill_color='#3186cc',
... ).add_to(map3)
<folium.features.CircleMarker object at 0x7fc1c7408a20>
>>> map3.save('/workspace/map3.html')

map3をブラウザで開きます。

map3_html.png

radiusで数量を表せそうなので、何らかの数値を都市ごとに反映してみます。

ここまで来るとインタラクティブな必要もないのでスクリプトを書きます。


都市ごとにマーカーを配置

import folium

map4 = folium.Map(location=[-30.159215, 138.955078], zoom_start=4)

# 各都市のデータを格納(本来はDBやcsvファイルから取得)
states = (
{'lat': -35.473468, 'lon': 149.012368, 'value': 1, 'name': 'Australian Capital Territory'},
{'lat': -31.253218, 'lon': 146.921099, 'value': 2, 'name': 'New South Wales'},
{'lat': -19.491411, 'lon': 132.550960, 'value': 3, 'name': 'Northern Territory'},
{'lat': -20.917574, 'lon': 142.702796, 'value': 4, 'name': 'Queensland'},
{'lat': -30.000232, 'lon': 136.209155, 'value': 5, 'name': 'South Australia'},
{'lat': -41.454520, 'lon': 145.970665, 'value': 6, 'name': 'Tasmania'},
{'lat': -37.471308, 'lon': 144.785153, 'value': 7, 'name': 'Victoria'},
{'lat': -27.672817, 'lon': 121.628310, 'value': 8, 'name': 'Western Australia'}
)

# 円の大きさをわかりやすくするための重み
WEIGHT = 100000

# 都市ごとにマーカーを追加(数が増えると辛いため、一括追加が今後の課題)
for state in states:
folium.CircleMarker(
[state['lat'], state['lon']],
radius=state['value'] * WEIGHT,
popup=state['name'],
color='#3186cc',
fill_color='#3186cc',
).add_to(map4)

map4.save('/workspace/map4.html')


上記のスクリプトを実行後、map4.htmlをブラウザで表示します。

map4_html.png

QuickStartの内容だけでも、なんとなくそれっぽい感じになりました。

もっとがっつり使うのであれば、Foliumのドキュメントに

元となったLeafletのドキュメントも合わせてチェックするのが良さそうです。


まとめ

サービスで提供する場合はGoogleMapsを使うことが多いと思いますが

調査や内部の提供であればこのようなライブラリも便利です。

記事中ではマーカーを置くまでの表層的な可視化に留まりましたが

地図自体の編集やポリゴンの配置など、様々な表現ができます。

Jupyter Notebookを使えばもっと対話的に分析ができるようなので

使ったことのある方は是非試してみてください。