You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 00:50:26