folium
是基於leaflet.js的python地圖套件,讓使用者可以很快速的使用python產生一些可互動的地圖。
我們可以很方便把加工後的GIS資料丟進去,並完成一個網頁地圖。
leaflet: [Day 13] WebGIS中的向量資料-在Leaflet實作 - iT 邦幫忙::一起幫忙解決難題,拯救 IT 人的一天
以下我們就快速來試一試
基本操作
安裝 folium
conda install -c conda-forge folium
初始化地圖
初始化地圖要指定地圖中心的經緯度坐標,跟比例尺(zomm_start)
例如:1
2
3import folium
m = folium.Map((25.0133904,121.52245),zoom_start=14)
m
folium內建一些基本的WMTS,使用tiles
,我們把它換成使用Cartodb Positron
1
2m = folium.Map((25.0133904,121.52245), tiles="Cartodb Positron",zoom_start=14)
m
當然,還有很多其他選擇,有需要的人可以自行參考
加入向量資料
folium的操作沒有很複雜,如果要加入向量資料,操作起來跟leaflet很像。
例如我們增加一個marker然後設定style及popup1
2
3
4
5
6
7
8
9
10m = folium.Map((25.0133904,121.52245),zoom_start=14)
folium.CircleMarker(
location=[25.0133904,121.52245],
radius=20,
popup='永和',
color='#3186cc',
fill=True,
fill_color='#3186cc'
).add_to(m)
m
若要丟整份資料,folium使用的格式是geojson,如果是Geopandas處理的資料,可以使用to_json()
這個方法將資料餵進去。
再次以新北的村里界資料為範例
先把資料準備好並轉好坐標系統為epsg43261
2
3
4
5
6
7import geopandas as gpd
village=gpd.read_file('data/village/village.shp',encoding='utf-8')
village=village[village.is_valid]
village=village[village['ADMIT']=='永和區']
village.crs = {'init' :'epsg:3826'} # 避免資料沒設,這邊再重新給一次
village=village.to_crs(epsg=4326)
village=village.reset_index()
處理好的資料是GeoDataFrame丟進去,可以用to_json轉為geojson
並直接丟進去folium
1 | m = folium.Map((25.0133904,121.52245),zoom_start=14) |
如果要增加圖層開關,讓瀏覽的時候比較方便,可以加入LayerControl(用法跟leaflet差不多)1
folium.LayerControl().add_to(m)
做個時序地圖
folium有一個滿好用的套件TimeSliderChoropleth
,
可以快速做一個時間序列的資料展示
他的基本操作如下:1
2
3
4g = TimeSliderChoropleth(
village.to_json(),
styledict = styledict,
).add_to(m)
其中,styledict定義的是時序資料的值
餵進去的資料需要按照要求
為了演示,我們針對village隨機產生時序資料1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18import pandas as pd
import numpy as np
n_periods = 24
n_sample = 12
assert n_sample < n_periods
dt_index = pd.date_range('2012-1-1', periods = n_periods, freq='M').strftime('%s')
styledata = { }
for item in village.index:
df = pd.DataFrame({'color': np.random.normal(size=n_periods),
'opacity': np.random.normal(size=n_periods)},
index = dt_index)
df = df.cumsum()
df.sample(n_sample, replace=False).sort_index()
styledata[item] = df
styledict = {str(country): data.to_dict(orient='index') for
country, data in styledata.items()}
產生的資料結構是長這樣
我們把向量圖丟進去,
並把上面產生的styledict也放進去1
2
3
4
5
6
7
8
9from folium.plugins import TimeSliderChoropleth
m = folium.Map((25.0133904,121.52245), tiles="Cartodb Positron",zoom_start=14)
g = TimeSliderChoropleth(
village.to_json(),
styledict = styledict,
).add_to(m)
m
參考資料
後記
folium還很很多功能,可以講個好幾天,之後幾天有機會再多看看吧!
今天的練習請參考github