foliumの基本的な使い方とオープンデータ活用


※ 初投稿になりますので、変な日本語や知識不足があるかもしれませんがご了承ください。

# はじめに

Pythonでデータ可視化といえば`Matplotlib`や`pandas`など代表的なライブラリを使ってグラフプロットすると思います。
実際はデータによりけりですが、オープンデータ（特に緯度経度が含まれているデータ）を可視化するとなると[QGIS](https://www.qgis.org/ja/site/)や[MANDARA](http://ktgis.net/mandara/)などのGIS（地理情報システム）ソフト、[GeoPandas](https://geopandas.org/)といったPythonのライブラリが挙げられます。

これらのソフトやライブラリは非常に使い勝手が良いのですが、`.shp`や`.gml`といったファイル形式やレイヤー管理といったGISの知識が多少なりとも持ち合わせていないと苦戦してしまう部分があります。

そこで、緯度経度が含まれているデータをPythonで簡単に地図上にプロットしたい、簡単に傾向を見たいと思って調べてみた結果、`folium`というPythonのライブラリを用いることで簡単に可視化することが出来るみたいです。

本記事では**foliumの基本的な使い方**から、**実際のオープンデータを用いた可視化**までを記述します。

# foliumの概要

foliumは`leaflet.js`というJavascriptで使用することのできるマップをPythonライブラリ化したものです。これにより、**Pythonで簡易的にマップを用いてデータの可視化**を行えます。

マップはOpenStreetMapが標準として使用できます。さらに、Mapboxといったマップも自身で取得した`API key`を用いることで利用可能になります。

2020年6月28日現在、foliumのバージョンは0.11.0です。

以下からドキュメントおよびGithubを参照することができます。

- Folium version 0.11.0 documentation：<https://python-visualization.github.io/folium/>
- Github：<https://github.com/python-visualization/folium>

# インストール

インストールはPythonの`pip`コマンドを使用します。

```python
pip install folium
```

また、Anacondaを利用している場合は`conda`コマンドでインストールします。

```python
conda install -c conda-forge folium
```

# 実行環境

本記事では、以下の実行環境にてfoliumを使用します。

- Windows 10
- Anaconda 3（conda 4.8.3）
- Python 3.7.7
- Jupyter Notebook 6.0.3
- folium 0.11.0

# 基本的な使い方

## 地図の表示

任意の地図範囲生成および表示を行います。
例として新宿駅を表示してみます。新宿駅の緯度は`35.690921`、経度は`139.700258`です。

```python
# -*- coding: utf-8 -*-

import folium

# 地図生成
folium_map = folium.Map(location=[35.690921, 139.700258], zoom_start=15)

# 地図表示
folium_map

```

![map_show.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663575/27675b65-b986-b47a-b96b-232ab25b368c.png)
`folium.Map`で地図の生成を行います。さらに`location`パラメータで緯度経度を指定、`zoom_start`パラメータで地図の表示範囲指定を行います。

## 地図の保存

地図を保存したい場合は`folium_map.save`を使用します。なお、保存形式は`.html`ファイル形式です。

```python
# -*- coding: utf-8 -*-

import folium

# 地図生成
folium_map = folium.Map(location=[35.690921, 139.700258],zoom_start=15)

# 地図保存
folium_map.save('shinjuku_station.html')

```

## マーカーのプロット

いよいよ、地図上にマーカーをプロットしていきます。マーカーを地図上にプロットしたい場合は`folium.Marker`を使用します。

```python
# -*- coding: utf-8 -*-

import folium

# 地図生成
folium_map = folium.Map(location=[35.690921, 139.700258],zoom_start=15)

# マーカープロット
folium.Marker(location=[35.690921, 139.700258]).add_to(folium_map)

# 地図表示
folium_map
```

![map_marker.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663575/79b04bb4-1208-041f-1a57-e0b90d341f1f.png)
マーカーのデフォルト色は青色のようです。

さらに、以下のようにパラメータを追加することで色の変更、アイコン変更、さらにはポップアップウィンドウを表示することが可能です。色の種類やアイコン等の詳細な情報は[こちら](https://github.com/python-visualization/folium/blob/3c8176fba474c4b1a2650ec75431a03553020502/folium/map.py#L526)に記述されています。

```python
# -*- coding: utf-8 -*-

import folium

# 地図生成
folium_map = folium.Map(location=[35.690921, 139.700258],zoom_start=15)

# マーカープロット（ポップアップ設定，色変更，アイコン変更）
folium.Marker(
    location=[35.690921, 139.700258],
    popup='Shinjuku Station',
    icon=folium.Icon(color='red', icon='home')
).add_to(folium_map)

# 地図表示
folium_map
```

![marker_change.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663575/49e75f8a-7020-a146-a843-59babdd0c4f0.png)
**※ Jupyter Notebook上でポップアップ設定をする場合、日本語は文字化けする仕様になっています。
&nbsp; &nbsp; 実際はfolium上で文字化けしているわけではないのでご安心ください。**

## サークルマーカーのプロット

地図上にサークルマーカーをプロットすることもできます。`folium.CircleMarker`を使用してプロットします。

```python
# -*- coding: utf-8 -*-

import folium

# 地図生成
folium_map = folium.Map(location=[35.690921, 139.700258],zoom_start=15)

# サークルマーカープロット(外径色は赤，内径色は青)
folium.CircleMarker(
    location=[35.690921, 139.700258],
    radius=40,
    color='#ff0000',
    fill_color='#0000ff'
).add_to(folium_map)

# 地図表示
folium_map
```

![circle_maker.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663575/dffacd50-f9de-9491-9aec-ed98794b6b7a.png)
`radius`パラメータでサークルマーカー範囲を指定、`color`パラメータで外径の色指定、`fill_color`パラメータで内径の色指定を行います。色の種類はHTMLやCSSで用いるカラーコードで指定します。

# 応用編

## 複数地点によるマーカープロット

複数の地点を一斉にプロットすることもできます。この場合は`pandas`と組み合わせて使用します。
例として、新宿駅・渋谷駅・上野駅・東京駅・高輪ゲートウェイ駅の5つを同時にマーカープロットしてみます。

```python
# -*- coding: utf-8 -*-

import folium
import pandas as pd

# データ格納（名前，緯度経度）
df = pd.DataFrame({
    'station': ['新宿駅', '渋谷駅', '上野駅', '東京駅', '高輪ゲートウェイ駅'],
    'latitude': [35.690921, 35.658034, 35.713768, 35.681236, 35.6355406],
    'longtude': [139.700258, 139.701636, 139.777254, 139.767125, 139.7407245],
})

# 地図生成（新宿駅中心）
folium_map = folium.Map(location=[35.690921, 139.700258], zoom_start=12)

# マーカープロット
for i, row in df.iterrows():
    folium.Marker(
        location=[row['latitude'], row['longtude']],
        popup=row['station'],
        icon=folium.Icon(color='red')
    ).add_to(folium_map)

# 地図表示
folium_map
```

![complex_markers.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663575/34be58bc-fb4d-6358-24cd-3f575d202b9c.png)

## オープンデータの活用

実際のオープンデータを用いて可視化してみたいと思います。
例として、東京都文京区のAED設置場所を設置台数ごとにマーカーの色を変更してプロットします。

なお、東京都オープンデータカタログサイトである[こちら](https://catalog.data.metro.tokyo.lg.jp/dataset/t131059d0000000002)からcsvファイル形式でダウンロードし、`UTF-8`形式で保存しました。

```python
# -*- coding: utf-8 -*-

import folium
import pandas as pd

# csvからのデータ読み込み(必要なカラムだけを抽出)
df = pd.read_csv('aedsettikasyoitiran.csv', usecols = ['名称','緯度','経度','設置台数'], encoding='utf-8')

# 欠損値削除
df = df.dropna()

# 地図生成（東京都文京区中心）
folium_map = folium.Map(location=[35.72349, 139.749553], zoom_start=14)

# マーカープロット
for i, row in df.iterrows():

    count = row['設置台数']
    if count == 1:
            folium.Marker(
                location=[row['緯度'], row['経度']],
                popup=row['名称'],
                icon=folium.Icon(color='red')
            ).add_to(folium_map)
    else:
        folium.Marker(
            location=[row['緯度'], row['経度']],
            popup=row['名称'],
            icon=folium.Icon(color='blue')
        ).add_to(folium_map)

# 地図表示
folium_map
```

![AED_marker.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663575/b8e4a009-e24f-bc2e-761d-08b513c7d6e4.png)
AEDの設置台数が**1台の場合は赤色**、**2台の場合は青色**となっていることが地図上で確認できます。

# おわりに

Pythonのfoliumを使うことでオープンデータも簡単に可視化することができました。この記事では紹介していませんが、地図をモノクロに変更・ヒートマップ作成など位置参照データに対して様々な可視化方法を実現することができます。

ぜひfoliumを使って可視化してみてください。結構面白いと思います（笑）

# 参考文献

以下の文献を参考にさせていただきました。

- [Folium: Python で地図可視化 - Tak's Notebook](https://takaishikawa42.hatenablog.com/entry/2019/01/11/234716)
- [Python: foliumでJupyter Notebookに地図を描画する](https://ohke.hateblo.jp/entry/2018/03/02/230000)
- [Pythonで地図上に緯度・経度を指定してプロットする - AI人工知能テクノロジー](https://newtechnologylifestyle.net/python_gpsprot/)