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

Plotly Python:Choropleth地图时间滑块与下拉菜单联动异常修复

问题:Choropleth地图年份切换功能异常

尝试创建带时间滑块(选择日期)和下拉菜单(选择数据集年份)的Choropleth地图,但年份选择功能失效:要么始终显示2020年数据,要么两年数据混合展示。需要实现:选择2019年时仅展示对应日期的2019数据,选择2020年时仅展示对应日期的2020数据。

错误原因

原代码核心问题:

  • 分别创建两年图表后合并trace,导致滑块仅对应2019年的日期步骤,下拉菜单的可见性逻辑未与滑块联动
  • 切换年份时,无法同步更新滑块的可选日期列表,也无法确保仅显示当前年份对应日期的单个trace

修复后的代码

import plotly.graph_objects as go
import pandas as pd

# 原始数据定义
data_2019 = pd.DataFrame({
    'year': 2019,
    'region': ['Germany', 'Denmark', 'Japan', 'France', 'Italy', 'Spain', 'Canada', 'Brazil', 'India', 'Australia',
               'China', 'Russia', 'South Korea', 'Netherlands', 'Sweden', 'Norway', 'Finland', 'Mexico',
               'Argentina', 'Chile',
               'Germany', 'Denmark', 'Japan', 'France', 'Italy', 'Spain', 'Canada', 'Brazil', 'India', 'Australia'],
    'date': ['01-01', '01-01', '01-01', '02-01', '02-01', '02-01', '03-01', '03-01', '03-01', '04-01',
             '04-01', '04-01', '05-01', '05-01', '05-01', '06-01', '06-01', '06-01', '07-01', '07-01',
             '08-01', '08-01', '08-01', '09-01', '09-01', '09-01', '10-01', '10-01', '10-01', '11-01'],
    'valence': [0.3, 0.25, 0.22, 0.21, 0.18, 0.15, 0.1, 0.12, 0.14, 0.15,
                0.17, 0.19, 0.21, 0.23, 0.25, 0.27, 0.29, 0.31, 0.33, 0.35,
                0.37, 0.39, 0.41, 0.43, 0.45, 0.47, 0.49, 0.51, 0.53, 0.55]
})

data_2020 = pd.DataFrame({
    'year': 2020,
    'region': ['Germany', 'Denmark', 'Japan', 'France', 'Italy', 'Spain', 'Canada', 'Brazil', 'India', 'Australia',
               'China', 'Russia', 'South Korea', 'Netherlands', 'Sweden', 'Norway', 'Finland', 'Mexico',
               'Argentina', 'Chile',
               'Germany', 'Denmark', 'Japan', 'France', 'Italy', 'Spain', 'Canada', 'Brazil', 'India', 'Australia'],
    'date': ['01-01', '01-01', '01-01', '02-01', '02-01', '02-01', '03-01', '03-01', '03-01', '04-01',
             '04-01', '04-01', '05-01', '05-01', '05-01', '06-01', '06-01', '06-01', '07-01', '07-01',
             '08-01', '08-01', '08-01', '09-01', '09-01', '09-01', '10-01', '10-01', '10-01', '11-01'],
    'valence': [0.94, 0.89, 0.85, 0.71, 0.67, 0.63, 0.81, 0.79, 0.77, 0.65,
                0.62, 0.61, 0.75, 0.72, 0.69, 0.85, 0.82, 0.79, 0.75, 0.72,
                0.91, 0.88, 0.84, 0.81, 0.78, 0.74, 0.9, 0.87, 0.83, 0.8]
})

# 合并两年数据
combined_data = pd.concat([data_2019, data_2020], ignore_index=True)

fig = go.Figure()

# 为所有年份-日期组合生成trace,并添加自定义属性区分
for year in combined_data['year'].unique():
    year_data = combined_data[combined_data['year'] == year]
    for date in year_data['date'].unique():
        df = year_data[year_data['date'] == date]
        fig.add_trace(go.Choropleth(
            locations=df['region'],
            z=df['valence'],
            locationmode='country names',
            colorscale='Viridis',
            colorbar_title='Valence',
            visible=False,
            # 添加自定义属性,方便后续筛选
            customdata={'year': year, 'date': date}
        ))

# 生成年份切换的按钮逻辑
def get_year_update_args(target_year):
    # 获取目标年份的所有日期
    target_dates = combined_data[combined_data['year'] == target_year]['date'].unique()
    # 生成可见性列表:仅目标年份的trace可见,且默认第一个日期的trace显示
    visible = []
    for trace in fig.data:
        trace_year = trace.customdata['year']
        trace_date = trace.customdata['date']
        visible.append(trace_year == target_year and trace_date == target_dates[0])
    
    # 生成对应年份的滑块步骤
    steps = []
    for i, date in enumerate(target_dates):
        # 找到该年份对应日期的trace索引
        trace_idx = [idx for idx, t in enumerate(fig.data) if t.customdata['year'] == target_year and t.customdata['date'] == date][0]
        step_visible = [False]*len(fig.data)
        step_visible[trace_idx] = True
        steps.append(dict(
            method='update',
            args=[{'visible': step_visible}],
            label=date
        ))
    
    return {
        'visible': visible,
        'sliders': [dict(active=0, pad={"t":50}, steps=steps)]
    }

# 更新布局:下拉菜单+初始滑块
fig.update_layout(
    updatemenus=[
        dict(
            buttons=[
                dict(
                    label='2019',
                    method='update',
                    args=[get_year_update_args(2019)]
                ),
                dict(
                    label='2020',
                    method='update',
                    args=[get_year_update_args(2020)]
                )
            ],
            direction="down",
            pad={"r":10, "t":10},
            showactive=True
        )
    ],
    # 初始显示2019年第一个日期的数据
    sliders=[dict(active=0, pad={"t":50}, steps=[
        dict(
            method='update',
            args=[{'visible': [t.customdata['year']==2019 and t.customdata['date']=='01-01' for t in fig.data]}],
            label='01-01'
        )
    ])]
)

fig.show()

关键改动说明

  • 合并数据统一管理:将两年数据合并,一次性生成所有年份-日期组合的trace,并通过customdata标记每个trace的年份和日期,方便后续筛选
  • 联动下拉菜单与滑块:切换年份时,不仅更新trace的可见性,同时替换滑块的步骤列表为当前年份的日期,确保滑块仅对应当前年份的可选日期
  • 精准控制可见性:每次切换年份或日期时,仅让单个目标trace可见,避免多数据叠加显示

内容的提问来源于stack exchange,提问作者phoebe_albeduddel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 23:23:15