Plotly Mapbox动画如何保留历史帧数据实现叠加显示?
实现Plotly Mapbox动画历史帧叠加的方案
Plotly Express的animation_frame默认会在切换帧时替换数据,要实现历史帧保留叠加的效果,需要手动构建累积数据集并配置动画轨迹,具体步骤如下:
1. 预处理累积数据集
先对周日期排序,然后为每个周生成包含当前周及之前所有周数据的子集:
# 按时间顺序排序周日期 sorted_weeks = sorted(collision_df['week_date_range'].unique()) # 生成每个周对应的累积数据集 cumulative_dfs = [] for week in sorted_weeks: cum_df = collision_df[collision_df['week_date_range'] <= week] cumulative_dfs.append((week, cum_df))
2. 手动构建带累积轨迹的动画
改用plotly.graph_objects创建图表,为每个累积帧添加事故轨迹,并配置动画控制:
import plotly.graph_objects as go # 初始化Mapbox图表 fig = go.Figure() # 定义事故严重程度的颜色映射 color_map = { 'Non-Fatal':'#272b9b', 'Fatal':'#b22f20' } # 为每个累积周添加事故轨迹 for i, (week, df) in enumerate(cumulative_dfs): # 添加非致命事故标记 non_fatal = df[df['accident_severity'] == 'Non-Fatal'] fig.add_trace(go.Scattermapbox( lat=non_fatal['latitude'], lon=non_fatal['longitude'], mode='markers', marker=dict( size=non_fatal['number_of_casualties'].clip(upper=10), color=color_map['Non-Fatal'], opacity=0.5 ), hovertext=[f"Severity: {row['accident_severity']}<br>Casualties: {row['number_of_casualties']}" for _, row in non_fatal.iterrows()], name=f"Non-Fatal ({week})", # 初始仅第一帧的轨迹可见,后续轨迹默认隐藏 visible=True if i == 0 else False )) # 添加致命事故标记 fatal = df[df['accident_severity'] == 'Fatal'] fig.add_trace(go.Scattermapbox( lat=fatal['latitude'], lon=fatal['longitude'], mode='markers', marker=dict( size=fatal['number_of_casualties'].clip(upper=10), color=color_map['Fatal'], opacity=0.5 ), hovertext=[f"Severity: {row['accident_severity']}<br>Casualties: {row['number_of_casualties']}" for _, row in fatal.iterrows()], name=f"Fatal ({week})", visible=True if i == 0 else False )) # 构建动画帧:每个帧控制对应累积轨迹的显示 frames = [] for i, week in enumerate(sorted_weeks): visible = [False] * len(fig.data) # 显示当前周及之前所有周的轨迹 for j in range(0, (i+1)*2): visible[j] = True frames.append(go.Frame( data=[fig.data[j].update(visible=visible[j]) for j in range(len(fig.data))], layout=go.Layout(title_text=f"UK Traffic Collisions up to {week}"), name=str(week) )) # 配置布局、播放按钮和滑块 fig.update_layout( mapbox_style='carto-positron', mapbox=dict( zoom=4.6, center={'lat': collision_df['latitude'].mean(), 'lon': collision_df['longitude'].mean()} ), updatemenus=[dict( type='buttons', buttons=[ dict( label='Play', method='animate', args=[None, dict( frame=dict(duration=500, redraw=True), fromcurrent=True, transition=dict(duration=0) )] ), dict( label='Pause', method='animate', args=[[None], dict( frame=dict(duration=0), mode='immediate' )] ) ] )], sliders=[dict( steps=[dict( method='animate', args=[[str(week)], dict(frame=dict(duration=500))], label=week ) for week in sorted_weeks], currentvalue=dict(prefix='Up to: ') )], title="UK Traffic Collisions - Cumulative Animation" ) # 绑定动画帧到图表 fig.frames = frames fig.show()
关键说明
- 放弃Plotly Express的自动动画,改用Graph Objects手动控制轨迹显示,实现累积叠加效果
- 每个动画帧对应显示到当前周为止的所有历史事故数据
- 通过
visible属性控制不同帧下的轨迹显示状态,配合滑块和播放按钮完成动画逻辑
内容的提问来源于stack exchange,提问作者MushyPete
相关产品推荐
相关产品推荐

