基于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
相关产品推荐
相关产品推荐

