>>> from env_helper import info; info()
页面更新时间: 2023-04-15 19:52:40
运行环境:
    Linux发行版本: Debian GNU/Linux 12 (bookworm)
    操作系统内核: Linux-6.1.0-7-amd64-x86_64-with-glibc2.36
    Python版本: 3.11.2

14.3. 使用Folium 进行WebGIS 应用

14.3.1. 在线资源

基本的用法:

添加用户数据:

14.3.2. Folium的基本用法

Folium是建立在Python系统数据整理(Data wrangling)和Leaflet.js 前端地图类库之上的开源库。 使用的思路一般是使用Python处理数据,然后Leaflet地图上进行可视化。

Folium能够将Python处理后的数据轻松地在交互式的Leaflet地图上进行可视化展示。它不单单可以在地图上展示数据的分布图,还可以使用Vincent/Vega在地图上加以标记。

这个开源库中有许多来自OpenStreetMap、MapQuest Open、MapQuestOpen Aerial、Mapbox和Stamen的内建地图元件,而且支持使用Mapbox或Cloudmade的API密钥来定制个性化的地图元件。 Folium支持GeoJSON和TopoJSON两种文件格式的叠加,也可以将数据连接到这两种文件格式的叠加层,最后使用color-brewer配色方案创建分布图。

14.3.3. 开始创建地图

创建底图,传入起始坐标到Folium地图中:

>>> import folium
>>> map_osm = folium.Map(location=[45.5236, -122.6750])
>>> map_osm.save('/tmp/xx_osm.html')

Folium默认使用的是OpenStreetMap地图切片,但是也可以使用 Stamen Terrain, Stamen Toner, Mapbox Bright 和 MapboxControl 数据源。

创建Folium对象时需要指定关键词:输入位置(location),切片(tiles),缩放比例(zoom):

>>> stamen = folium.Map(location=[45.5236, -122.6750], tiles='Stamen Toner', zoom_start=13)
>>> stamen.save('/tmp/xx_stamen_toner.html')

Folium也支持Cloudmade 和 Mapbox个性化定制的地图元件,只需简单地传入API_key :

最后,Folium支持传入任何与 Leaflet.js 兼容的地图服务接口:

>>> tileset = r'http://{s}.tiles.yourtiles.com/{z}/{x}/{y}.png'
>>> map = folium.Map(location=[45.372, -121.6972], zoom_start=12,
>>>                  tiles=tileset, attr='My Data Attribution')

14.3.4. 地图标记

Folium支持多种标记类型的绘制,下面从一个简单的Leaflet类型位置标记弹出文本开始:

>>> # map_1 = folium.Map(location=[45.372, -121.6972], zoom_start=12, tiles='Stamen Terrain')
>>>
>>> map_1 = folium.Map(location=[45.372, 121.6972],
>>>                        zoom_start=5,
>>>                        control_scale=True,
>>>                        control=False,
>>>                        tiles=None
>>>                        )
>>>
>>> folium.TileLayer(tiles='http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}',
>>>                          attr="&copy; <a href=http://ditu.amap.com/>高德地图</a>",
>>>                          min_zoom=0,
>>>                          max_zoom=19,
>>>                          control=True,
>>>                          show=True,
>>>                          overlay=False,
>>>                          name='高等'
>>>                          ).add_to(map_1)
>>>
>>>
>>>
>>> folium.Marker([45.3288, -121.6625], popup='Mt. Hood Meadows').add_to(map_1)
>>> folium.Marker([45.3311, -121.7113], popup='Timberline Lodge').add_to(map_1)
>>> map_1.save('xx_mthood.html')

Folium支持多种颜色和标记图标类型:

>>> map_1 = folium.Map(location=[45.372, -121.6972], zoom_start=12,tiles='Stamen Terrain')
>>> folium.Marker([45.3288, -121.6625], popup='Mt. Hood Meadows',
>>>                    icon = folium.Icon(icon = 'cloud')).add_to(map_1)
>>> folium.Marker([45.3311, -121.7113], popup='Timberline Lodge',
>>>                    icon = folium.Icon(color ='green')).add_to(map_1)
>>> folium.Marker([45.3300, -121.6823], popup='Some Other Location',
>>>                    icon = folium.Icon(color ='red')).add_to(map_1)
>>> # map_1.save('/tmp/xx_iconTest.html')
<folium.map.Marker at 0x7f7649023bd0>
>>> map_1
Make this Notebook Trusted to load map: File -> Trust Notebook

Folium也支持使用个性化的尺寸和颜色进行圆形标记:

>>> map_2 = folium.Map(location=[45.5236, -122.6750], tiles='Stamen Toner',
>>>                    zoom_start=13)
>>> folium.Marker(location=[45.5244, -122.6699], popup='The Waterfront').add_to(map_2)
>>> folium.CircleMarker(location=[45.5215, -122.6261], radius=500,
>>>                     popup='Laurelhurst Park', color='#3186cc',
>>>                     fill_color='#3186cc').add_to(map_2)
>>> map_2.save('/tmp/xx_portland.html')

Folium有一个简便的功能:可以使经/纬度悬浮显示在地图上:

>>> map_3 = folium.Map(location=[46.1991, -122.1889], tiles='Stamen Terrain',
>>>                    zoom_start=13)
>>> folium.LatLngPopup().add_to(map_3)
>>> map_3.save('/tmp/xx_sthelens.html')
>>> map_3
Make this Notebook Trusted to load map: File -> Trust Notebook

Click-for-marker功能允许标记动态放置:

>>> map_4 = folium.Map(location=[46.8527, -121.7649], tiles='Stamen Terrain',
>>>                    zoom_start=13)
>>> folium.Marker(location=[46.8354, -121.7325], popup='Camp Muir').add_to(map_4)
>>> folium.ClickForMarker(popup='Waypoint').add_to(map_4)
>>> map_4.save('/tmp/xx_mtrainier.html')
>>> # map_4

Folium也支持来自Leaflet-DVF(Data Visualization Framework,数据可视化框架)的Polygon(多边形)标记集:

>>> map_5 = folium.Map(location=[45.5236, -122.6750], zoom_start=13)
>>> folium.RegularPolygonMarker(location=[45.5012, -122.6655], popup='Ross Island Bridge',
>>>                    fill_color='#132b5e', number_of_sides=3, radius=10).add_to(map_5)
>>> folium.RegularPolygonMarker(location=[45.5132, -122.6708], popup='Hawthorne Bridge',
>>>                    fill_color='#45647d', number_of_sides=4, radius=10).add_to(map_5)
>>> folium.RegularPolygonMarker(location=[45.5275, -122.6692], popup='Steel Bridge',
>>>                    fill_color='#769d96', number_of_sides=6, radius=10).add_to(map_5)
>>> folium.RegularPolygonMarker(location=[45.5318, -122.6745], popup='Broadway Bridge',
>>>                    fill_color='#769d96', number_of_sides=8, radius=10).add_to(map_5)
>>> map_5.save('/tmp/xx_bridges.html')
>>> # map_5

Leaflet DVF是Leaflet JavaScript映射库的扩展。该框架的主要目标是简化使用Leaflet的数据可视化和主题映射,从而更轻松地将原始数据转换为引人入胜的地图。

14.3.5. Folim 进阶用法

Vincent/Vega标记

Folium可通过vincent 进行任何类型的标记,并将标记悬浮在地图上。

单击出会出现框图。

Vincent:一个从Python到Vega的翻译器 Vega让D3建立可视化变得容易,而Vincent让Python建立Vega变得容易。Vincent接收Python数据结构并把它们翻译成Vega的可视化语法。通过对语法元素的获取和设置,它允许可视化设计的快速迭代,并把最终可视化结果输出到JSON。最重要的是,Vincent以一种直观的方式与Pandas DataFrames和Series相通。 详细信息请参考:https://vincent.readthedocs.org/en/latest/

>>> import json
>>> import folium
>>> buoy_map = folium.Map(location=[46.3014, -123.7390], zoom_start=7,tiles='Stamen Terrain')
>>> popup1 = folium.Popup(max_width=800,).add_child(folium.Vega( json.load(open('/gdata/folium/data/vis1.json')), width=500, height=250))
>>> folium.RegularPolygonMarker([47.3489, -124.708], fill_color='#43d9de', radius=12, popup=popup1).add_to(buoy_map)
<folium.features.RegularPolygonMarker at 0x7f23226c7cd0>
>>> popup2 = folium.Popup(max_width=800,).add_child(folium.Vega(json.load(open('/gdata/folium/data/vis2.json')), width=500, height=250))
>>> folium.RegularPolygonMarker([44.639, -124.5339], fill_color='#43d9de', radius=12, popup=popup2).add_to(buoy_map)
>>> popup3 = folium.Popup(max_width=800,).add_child(folium.Vega(json.load(open('/gdata/folium/data/vis3.json')), width=500, height=250))
>>> folium.RegularPolygonMarker([46.216, -124.1280], fill_color='#43d9de', radius=12, popup=popup3).add_to(buoy_map)
>>> buoy_map.save('/tmp/xx_NOAA_buoys.html')
>>> # buoy_map

GeoJSON/TopoJSON层叠加

GeoJSON 和TopoJSON层都可以导入地图,不同的层可以在同一张地图上可视化出来:

>>> geo_path = '/gdata/folium/data/antarctic_ice_edge.json'
>>> topo_path = '/gdata/folium/data/antarctic_ice_shelf_topo.json'
>>>
>>> ice_map = folium.Map(location=[-59.1759, -11.6016],
>>>                    tiles='Stamen Terrain', zoom_start=2)

分布图

Folium 允许 PandasDataFrames/Series 类型和 Geo/TopoJSON 类型之间的数据转换。 Color Brewer 颜色方案也是内建在这个库,可以直接地导入快速可视化的不同组合:

>>> import folium
>>> import pandas as pd
>>>
>>> state_geo = '/gdata/folium/data/us-states.json'
>>> state_unemployment = '/gdata/folium/data/US_Unemployment_Oct2012.csv'
>>>
>>> state_data = pd.read_csv(state_unemployment)
>>>
>>> # Let Folium determine the scale
>>> map1 = folium.Map(location=[48, -102], zoom_start=3)

基于D3阈值尺度,Folium在右上方创建图例,通过分位数创建最佳猜测值,使得导入设定的阈值简单化:

>>> map2 = folium.Map(location=[48, -102], zoom_start=3)

通过Pandas DataFrame进行数据处理,可以快速可视化不同的数据集。下面的例子中,df DataFrame包含6列不同的经济数据,我们将在下面可视化一部分数据: