Folium
https://python-visualization.github.io/folium/
統計データを、国や地域、道路など地図上に可視化する需要が高まっています。Foliumは、オープンソースのJavaScriptライブラリLeafletをバースとした Pythonライブラリで、これを利用すると、地図上にインタラクティブにデータを可視化することができます。
Folium がデフォルトで利用する地図情報は OpenStreetMap です。
はじめに
Folium のインストールとインポート
Python 言語のライブラリとしてのインストールになるので、一般の Python3 の環境であれば、Terminalから以下のコマンドでインストールできます。
$ pip3 install folium
import する際は、以下のように記述するのが一般的です。
import folium
Google Colaboratory では Jupyter Notebook で利用できるライブラリーが「すべてインストール済み」という前提なので、ローカル環境での作業のように、必要なライブラリのインストールを行う必要はなく、コードセルに import 文を書くだけで使うことができます。
Foliumの基本
以下のメソッドを用いることで、緯度・経度の値を使ったマーカー表示や、ヒートマップの表示、また GeoJSON形式の地理情報と統計情報を合わせた各種の可視化が可能になります。
- folium.Map( ):ベースとなる地図を生成します
- folium.Marker( ):地図上にマーカーを表示します
- folium.Circle( ):地図上に円を表示します
- folium.Choropleth( ):コロプレス図を生成します
- HeatMap( ):ヒートマップを生成します
地図生成のための関連知識
緯度・経度情報を取得するには
- GoogleMap を使う
地図上で目的の場所をダブルクリックすると、マーカーが表示されるとともに住所と緯度・経度が表示されます。
- GeoJSON.io を使う
https://geojson.io/
地図上でマーカーツールを選択して目的の場所をクリックすると右サイドに GeoJSON形式のデータが表示されます。"coordinates" として表示される最初の数字が経度、次の数字が緯度になっています。
GeoJSONデータとは
- GeoJSONは、地理情報を JSON 形式で記述したものです。
> JSON#GeoJSON
コロプレス図とは
コロプレス図とは、統計数値を地図上に表現したもので、区域単位(国別など)の情報を、統計値に応じた色彩や明暗によって表します。人口やGDP、生産高など、土地の上に分布するものを表現するのに適しています。
サンプル
サンプルコード
JupyterNotebook形式(.ipynb)でプログラムを提供します。
https://github.com/koichi-inoue/JupyterNotebook/blob/master/GeographicVisualization.ipynb
サンプルで利用しているサンプルデータ
- 全国の医療機関の医療提供状況(内閣官房 新型コロナ感染症対策)
- 掲載サイト(永続的に利用可能かどうかは不透明)
- Data:covid-19_daily_survey.csv
- DataURL:https://covid-19-surveillance.s3-ap-northeast-1.amazonaws.com/public_data/covid-19_daily_survey.csv
- URLから直接読み込んで利用します。
- Annotated geo-json geometry files for the world
- 掲載サイト:https://github.com/johan/world.geo.json
- Data:countries.geo.json
- DataURL:https://raw.githubusercontent.com/johan/world.geo.json/master/countries.geo.json
- URLから直接読み込んで利用します。
- plotly に同梱されている「世界各国の一人当たりのGDP(2007年)」
- ライブラリから読み込むため、準備不要です。
プログラムの解説
基本的な地図の描画(Folium)
- 基本的な地図は、以下の様に記述することで表示されます。
map0 = folium.Map( location = [35,139] , zoom_start = 5.0 , tiles="OpenStreetMap" ) map0
- パラメータ
- location:地図の中心とする位置(緯度・経度)
- zoom_start:初期表示倍率
- tiles:地図のスタイル
- width:地図の幅
- height:地図の高さ
- 地図タイルには、以下のようなものが利用できます。
- OpenStreetMap:デフォルト
- Stamen Terrain, Stamen Watercolor, Stamen Toner
- Mapbox Bright:Limited levels of zoom for free tiles
- Mapbox Control Room:Limited levels of zoom for free tiles
地図上にマーカーを表示(Folium)
- 九州産業大学の座標を変数に定義
ksu_lat = 33.66983627668292 ksu_lng = 130.44487416744232
- folium.Map 関数でベースとなる地図を作成
map1 = folium.Map( location = [ksu_lat, ksu_lng] , zoom_start = 20 )
- folium.Marker 関数でマーカーを定義
folium.Marker( location = [ksu_lat, ksu_lng] , popup="九州産業大学" ).add_to( map1 )
地図上にサークルを表示(Folium)
上と同様につき、省略します。
ヒートマップの描画(Folium)
- オープンデータ covid-19_daily_survey.csv を df に読み込み
df = pd.read_csv('https://covid-19-surveillance・・covid-19_daily_survey.csv')
本日最新のデータがこのURLから直接読まれます。
- ベースとなる地図を map3 として描画
map3 = folium.Map( location = [TOKYO_lat, TOKYO_lng] , zoom_start = 11 , tiles="cartodbpositron" )
- 入院・通常 に該当する病院の座標情報を df_hospital に回収
df_hospital = df.query( "医療区分=='入院' & 医療区分回答=='通常'" ).loc[:,['緯度','経度']]
- ヒートマップ用の変数 df_hospital_geolist に df_hospital の値をリスト登録
df_hospital_geolist = df_hospital.values.tolist()
- 各医療機関の座標を半径7 ぼかし5 で map3 に追加
HeatMap( df_hospital_geolist, radius=7, blur=5 ).add_to(map3)
GeoJSON データを活用したコロプレス図(Folium)
- 世界の区画データの読み込み(テキストを json 形式のデータとして読み込み)
url = requests.get('https://raw.githubusercontent.com/johan/world.geo.json/master/countries.geo.json') text = url.text geo_json = json.loads( text)
- plotlyに同梱されている gapminder 2007年のデータを読み込み
df_gm = px.data.gapminder().query("year == 2007")
- folium.Map 関数でベースとなる地図を作成
map4 = folium.Map( location = [40,0] , zoom_start = 1.8 )
- folium.Choropleth 関数でコロプレス図を定義
folium.Choropleth( geo_data = geo_json, data = df_gm, fill_opacity = 1, line_color = 'white' , nan_fill_color = '#888888' , # 欠損値の色 columns = ['iso_alpha' , 'gdpPercap'], # 色分けに使うキーとカラム名 key_on = 'feature.id' , # データに対応した geo.json のキー fill_color = 'OrRd', ).add_to(map4)
plotly.express による地球儀(plotly)
- 地球儀に国名をドットで表示
df_gm = px.data.gapminder().query("year == 2007") fig0 = px.scatter_geo( df_gm, locations="iso_alpha", color="continent", projection="orthographic") fig0.show()
- 地球儀に gapminder の各国の人口(2007年)を重ねて表示
df_gm = px.data.gapminder().query("year == 2007") fig1 = px.scatter_geo( df_gm, locations='iso_alpha', color='continent', hover_name='country', size='pop', projection='orthographic' ) fig1.show()