folium是JavaScript下一个有名的开源库leaflet在python下的移植版,其内置了许多强大的地图自定义功能,本文将用它实现自定义地图样式及自定义区域的分级统计图(Choropleth map)。
folium的默认地图是OpenStreetMap,但说实话,这个地图不是那么美观,它同时也提供了几个内置的风格迥异的地图样式,可惜也不合我胃口。好在folium提供了自定义地图样式的功能,只要拥有地图瓦片(tile)的地址,我们就可自定义地图样式及风格,代码如下
import folium
map = folium.Map(
location=[39.30029918615029, 103.88671875], # 初始化地图中心
zoom_start=4,# 初始化放大级别
# 设置地图样式,可选择其他瓦片(tile)
tiles=('https://api.tiles.mapbox.com/v4/mapbox.streets/{z}/{x}/{y}.png'
+ '?access_token=pk.eyJ1IjoibHVrYXNtYXJ0aW5lbGxpIiwiYSI6ImNpem8'
+ '5dmhwazAyajIyd284dGxhN2VxYnYifQ.HQCmyhEXZUTz3S98FMrVAQ'),
attr='China' # 显示在地图右下角的自定义文字
)
# map # 在jupyter使用这句可直接显示地图
map.save('map.html') # 保存到当前工作目录下
效果如下
这里提供几个瓦片地址
Mapbox:https://api.tiles.mapbox.com/v4/mapbox.streets/{z}/{x}/{y}.png?access_token={此处填mapbox的token,需注册,也可直接使用上面代码中的token}
高德:http://wprd0{1-4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=1&style=7,{1-4}表示从1到4任选一个数字填入,参数意义参考https://blog.csdn.net/qq_35732147/article/details/81317693,效果如下
谷歌:http://www.google.cn/maps/vt?lyrs=m@189&gl=cn&x={x}&y={y}&z={z},更多风格参考https://blog.csdn.net/qq_16064871/article/details/78869326,效果如下
如果你已经有了geojson格式的数据以及各个区域的统计值之类的数据(用于控制颜色深浅),那么可以按照类似如下操作将该数据转换为绘制所需格式的geojson数据:
import geojson
from geojson import Feature, FeatureCollection, Polygon
import numpy as np
with open('district.geojson', 'rb') as f:
districts = geojson.load(f) # 读取geojson格式文件
features = [] # 保存各个区域geojson信息
color = [] # 保存区域id及对应颜色深浅相对值
for idx, geometry in enumerate(districts['features']): # 提取所有区域
# 获取经纬度列表[[lon, lat], ...],两次[0]是由于该列表被嵌套在两层列表中
circle = geometry['geometry']['coordinates'][0][0]
#染色区域id,颜色相对深度, 这里设置为0~100的随机数
color.append([str(idx), np.random.randint(100)])
polygon = Polygon([circle]) # 区域经纬度
features.append(Feature(
id=str(idx), # 指定geojson的id值,染色时使用该id与color中的idx匹配
geometry=polygon
))
feature_collection = FeatureCollection(features) # 生成绘制所需格式的geojson
这里提供两个获取geojson的网站:
数据准备完成之后,可以开始绘制Choropleth map了,代码如下:
import folium
import pandas as pd
map = folium.Map(
location=[39.30029918615029, 103.88671875], # 初始化地图中心
zoom_start=4,# 初始化放大级别
# 设置地图样式,可选择其他瓦片(tile)
tiles=('https://api.tiles.mapbox.com/v4/mapbox.streets/{z}/{x}/{y}.png'
+ '?access_token=pk.eyJ1IjoibHVrYXNtYXJ0aW5lbGxpIiwiYSI6ImNpem8'
+ '5dmhwazAyajIyd284dGxhN2VxYnYifQ.HQCmyhEXZUTz3S98FMrVAQ'),
attr='China' # 显示在地图右下角的自定义文字
)
folium.Choropleth(
geo_data=feature_collection, # 传入geojson
name='choropleth',
data=pd.DataFrame(color, columns=['idx','color']), # 颜色数据
columns=['idx','color'], # 染色区域id,颜色相对深度列名
key_on='feature.id', # geojson区域id
fill_color='BuPu', # 颜色样式
fill_opacity=0.5, # 区域透明度
line_opacity=0.2, # 边缘透明度
legend_name='Rank' #图例名
).add_to(map)
# map # 在jupyter使用这句可直接显示地图
map.save('map.html') # 保存到当前工作目录下
这里我使用的是中国各省的geojson格式文件,最终效果如下
2020.01.03更新:补充代码中未导入的库,更换mapbox token修复token失效导致的加载地图失败
2020.01.08更新:增加了高德地图与谷歌地图的显示效果
folium示例:http://python-visualization.github.io/folium/quickstart.html#Choropleth-maps
folium API:http://python-visualization.github.io/folium/modules.html#module-folium.features ↩︎