Python Folium:如何实现地图数据随时间动态变色展示
刚好我之前折腾过类似的需求,用Folium自带的TimeSliderChoropleth插件就能完美解决你要的单张地图上颜色随时间动态变化的效果——完全不用去凑时序热力图的热闹,那个更适合点数据的密度变化,和你的区域着色场景不搭。下面给你具体的实现步骤和代码,完全适配你现有的失业数据场景:
核心思路
TimeSliderChoropleth是Folium专门为区域着色地图设计的时序插件,能在同一张地图上通过滑块切换不同时间点的着色效果,完美衔接你已经能生成单张着色地图的现有代码。
前提准备
首先你需要整理好多时间点的失业数据:
- 如果你现在只有Nov2012的数据,可以复制几份原文件,修改失业率数值模拟Oct2012、Dec2012的数据(格式和
US_Unemployment_Nov2012.csv保持一致,列名保留State、Unemployment) - 或者把所有时间的数据合并成一个宽格式DataFrame,列名设为
State、Oct2012、Nov2012、Dec2012,每一行对应一个州的各月失业率
具体代码实现
假设你已经有美国州的GeoJSON文件(就是Folium官方示例里的us-states.json),以及多月份的失业数据,直接套用下面的代码即可:
import folium import pandas as pd from folium.plugins import TimeSliderChoropleth import json import branca.colormap as cm # 1. 读取地理边界数据 with open('us-states.json') as f: states_geo = json.load(f) # 2. 读取并合并多时间点的失业数据(替换成你自己的真实文件路径) oct_data = pd.read_csv('US_Unemployment_Oct2012.csv') nov_data = pd.read_csv('US_Unemployment_Nov2012.csv') dec_data = pd.read_csv('US_Unemployment_Dec2012.csv') # 合并数据,给各月失业率列加后缀区分 merged_data = oct_data.merge(nov_data, on='State', suffixes=('_oct', '_nov')) merged_data = merged_data.merge(dec_data, on='State').rename(columns={'Unemployment': 'Unemployment_dec'}) # 3. 建立州名到GeoJSON中ID的映射(GeoJSON里用州缩写作为ID,比如'AL') state_id_map = {} for feature in states_geo['features']: feature['id'] = feature['properties']['abbr'] state_id_map[feature['properties']['name']] = feature['id'] # 4. 生成插件需要的时序数据格式:嵌套字典 styledata = {} for idx, row in merged_data.iterrows(): state_id = state_id_map[row['State']] # 时间用YYYY-MM格式,插件会自动按时间排序 styledata[state_id] = { '2012-10': {'color': '', 'opacity': 0.7, 'value': row['Unemployment_oct']}, '2012-11': {'color': '', 'opacity': 0.7, 'value': row['Unemployment_nov']}, '2012-12': {'color': '', 'opacity': 0.7, 'value': row['Unemployment_dec']} } # 5. 设置统一的颜色映射(和你单张地图的配色逻辑一致) all_unemployment_values = merged_data[['Unemployment_oct', 'Unemployment_nov', 'Unemployment_dec']].values.flatten() colormap = cm.LinearColormap( colors=['#f7fbff', '#08306b'], # 浅蓝到深蓝,可替换成你喜欢的配色 vmin=all_unemployment_values.min(), vmax=all_unemployment_values.max() ) # 给每个时间点的数值分配对应颜色 for state_id in styledata: for date in styledata[state_id]: styledata[state_id][date]['color'] = colormap(styledata[state_id][date]['value']) # 6. 创建地图并添加时间滑块图层 m = folium.Map(location=[37, -102], zoom_start=4) # 美国地图中心位置 TimeSliderChoropleth( data=states_geo, styledata=styledata, name='US Unemployment Time Series', overlay=True, control=True ).add_to(m) # 添加颜色图例 colormap.add_to(m) # 保存动态地图 m.save('us_unemployment_dynamic.html')
关键细节说明
- 数据格式适配:插件要求的
styledata是嵌套字典,外层键是地理要素的ID(州缩写),内层键是可排序的时间字符串,值包含颜色、透明度和数值,这样滑块切换时才能精准匹配对应时间的着色。 - 颜色统一:这里用的
LinearColormap和你单张着色地图的逻辑完全一致,确保不同时间点的颜色尺度统一,避免视觉混淆。 - 衔接现有代码:如果你之前已经有读取单月数据和GeoJSON的代码,只需要替换数据合并部分,生成
styledata即可,原有逻辑不用大改。
测试调整技巧
- 暂时没有多时间数据的话,复制原文件修改数值模拟即可,先跑通流程再替换真实数据。
- 配色可以自定义,比如用
['#fee5d9', '#cb181d']的红系配色,更直观体现失业率高低。
内容的提问来源于stack exchange,提问作者kww




