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

基于DataFrame列唯一值创建Plotly下拉控件遇问题求助

问题描述

我有如下简单的DataFrame:

import requests
import pandas as pd
from pandas import DataFrame
import matplotlib.pyplot as plt
import seaborn as sns

# Intitialise data of lists
data = [{'Month': '2020-01-01', 'Expense':1000, 'ID':'123'}, 
       {'Month': '2020-02-01', 'Expense':3000, 'ID':'123'},
       {'Month': '2020-03-01', 'Expense':2000, 'ID':'123'}, 
       {'Month': '2020-01-01', 'Expense':3000, 'ID':'456'},
       {'Month': '2020-02-01', 'Expense':5000, 'ID':'456'}, 
       {'Month': '2020-03-01', 'Expense':10000, 'ID':'456'},
       {'Month': '2020-03-01', 'Expense':5000, 'ID':'789'},
       {'Month': '2020-04-01', 'Expense':2000, 'ID':'789'},
       {'Month': '2020-05-01', 'Expense':3000, 'ID':'789'}]
df = pd.DataFrame(data)
df

我希望基于ID列中的唯一值创建一个下拉控件,测试了如下代码,但无法生成图表:

uniques = df['ID'].unique()

# plotly
fig = go.Figure()

# set up ONE trace
fig.add_trace(go.Scatter(x=df.index,
                         y=df[df.columns[0]],
                         visible=True)
             )

updatemenu = []
buttons = []

# button with one option for each dataframe
for i in uniques:
    #print(i)
    #df_single = df[df['ID']==i]
    #data=df_single
    #print(data)
     
     buttons.append(dict(method='restyle',
                         label=i,
                         visible=True,
                         args=[{'y':[df['ID']==i],
                                'x':[df.index],
                                'type':'scatter'}]
                         )
                   )

    
# some adjustments to the updatemenus
updatemenu = []

your_menu = dict()
updatemenu.append(your_menu)

updatemenu[0]['buttons'] = buttons
updatemenu[0]['direction'] = 'down'
updatemenu[0]['showactive'] = True

# add dropdown menus to the figure
fig.update_layout(showlegend=False, updatemenus=updatemenu)
fig.show()

请问我的代码哪里出错了?


错误分析

你的代码存在三个核心问题:

  • 初始Trace数据错误:初始添加的Trace中,y=df[df.columns[0]]取的是Month列的字符串值,Scatter图无法将字符串作为y轴数据渲染,这是图表无法显示的直接原因。
  • 按钮参数数据错误:{'y':[df['ID']==i]}返回的是布尔值数组,不是对应ID的Expense数值数据,完全不符合图表需求。
  • x轴逻辑不合理:使用df.index作为x轴,无法体现月度时间维度,同时不同ID的时间范围不同,也会导致数据匹配混乱。

修正后的代码

首先确保导入plotly的graph_objects模块:

import plotly.graph_objects as go

然后使用以下代码创建正常工作的下拉控件图表:

uniques = df['ID'].unique()

# 将Month列转为日期格式,保证x轴时间刻度渲染正常
df['Month'] = pd.to_datetime(df['Month'])

fig = go.Figure()

# 初始化第一个ID的Trace,确保图表初始有可渲染的正确数据
first_id = uniques[0]
df_first = df[df['ID'] == first_id]
fig.add_trace(go.Scatter(x=df_first['Month'],
                         y=df_first['Expense'],
                         name=first_id,
                         visible=True))

buttons = []

# 为每个ID生成对应的按钮配置
for id_val in uniques:
    df_filtered = df[df['ID'] == id_val]
    buttons.append(dict(
        method='restyle',
        label=id_val,
        args=[{
            'x': [df_filtered['Month']],
            'y': [df_filtered['Expense']],
            'name': [id_val]
        }]
    ))

# 配置下拉菜单的位置与样式
updatemenu = [{
    'buttons': buttons,
    'direction': 'down',
    'showactive': True,
    'x': 0.1,
    'xanchor': 'left',
    'y': 1.1,
    'yanchor': 'top'
}]

# 完善图表布局
fig.update_layout(
    updatemenus=updatemenu,
    xaxis_title='月份',
    yaxis_title='支出',
    title='不同ID的月度支出趋势'
)

fig.show()

代码说明
  • 先转换Month列为日期类型,让x轴能正确显示时间刻度,符合业务逻辑。
  • 初始Trace使用第一个ID的真实支出数据,保证图表加载时就有可正常渲染的内容。
  • 每个按钮的args传入对应ID过滤后的月度和支出数据,确保切换下拉选项时图表显示正确内容。
  • 调整下拉菜单位置,避免遮挡标题,提升视觉体验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 09:14:51