使用Plotly.graph_objects制作带滑块的新冠数据堆叠水平柱状图问题求助
解决方案
问题根因
- 第一个问题:循环内重复创建
go.Figure对象,之前月份的trace会被覆盖,最终仅保留最后一个月的2条数据(女性、男性各1条),所以滑块仅显示2个步骤 - 第二个问题:滑块切换逻辑错误,每个步骤仅单条trace可见,缺少堆叠需要的2条数据,且未全局固定堆叠模式,导致堆叠效果消失
修复后完整代码
import pandas as pd import plotly.graph_objects as go from pandas import Timestamp # 构造示例数据集 df = pd.DataFrame({'index': [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23], 'columns': ['Fecha', 'Edad', 'Sexo', 'Casos', 'Mes-Año'], 'data': [[Timestamp('2020-03-31 00:00:00'),'20 - 30','FEMENINO',4,'Mar-20'], [Timestamp('2020-03-31 00:00:00'), '20 - 30', 'MASCULINO', 5, 'Mar-20'], [Timestamp('2020-03-31 00:00:00'), '30 - 40', 'FEMENINO', 2, 'Mar-20'], [Timestamp('2020-03-31 00:00:00'), '30 - 40', 'MASCULINO', 8, 'Mar-20'], [Timestamp('2020-04-30 00:00:00'), '20 - 30', 'FEMENINO', 26, 'Apr-20'], [Timestamp('2020-04-30 00:00:00'), '20 - 30', 'MASCULINO', 59, 'Apr-20'], [Timestamp('2020-04-30 00:00:00'), '30 - 40', 'FEMENINO', 57, 'Apr-20'], [Timestamp('2020-04-30 00:00:00'), '30 - 40', 'MASCULINO', 129, 'Apr-20'], [Timestamp('2020-05-31 00:00:00'), '20 - 30', 'FEMENINO', 61, 'May-20'], [Timestamp('2020-05-31 00:00:00'), '20 - 30', 'MASCULINO', 92, 'May-20'], [Timestamp('2020-05-31 00:00:00'), '30 - 40', 'FEMENINO', 131, 'May-20'], [Timestamp('2020-05-31 00:00:00'), '30 - 40', 'MASCULINO', 373, 'May-20'], [Timestamp('2020-06-30 00:00:00'), '20 - 30', 'FEMENINO', 93, 'Jun-20'], [Timestamp('2020-06-30 00:00:00'), '20 - 30', 'MASCULINO', 121, 'Jun-20'], [Timestamp('2020-06-30 00:00:00'), '30 - 40', 'FEMENINO', 190, 'Jun-20'], [Timestamp('2020-06-30 00:00:00'), '30 - 40', 'MASCULINO', 426, 'Jun-20'], [Timestamp('2020-07-31 00:00:00'), '20 - 30', 'FEMENINO', 91, 'Jul-20'], [Timestamp('2020-07-31 00:00:00'), '20 - 30', 'MASCULINO', 117, 'Jul-20'], [Timestamp('2020-07-31 00:00:00'), '30 - 40', 'FEMENINO', 192, 'Jul-20'], [Timestamp('2020-07-31 00:00:00'), '30 - 40', 'MASCULINO', 382, 'Jul-20'], [Timestamp('2020-08-31 00:00:00'), '20 - 30', 'FEMENINO', 85, 'Aug-20'], [Timestamp('2020-08-31 00:00:00'), '20 - 30', 'MASCULINO', 148, 'Aug-20'], [Timestamp('2020-08-31 00:00:00'), '30 - 40', 'FEMENINO', 197, 'Aug-20'], [Timestamp('2020-08-31 00:00:00'), '30 - 40', 'MASCULINO', 338, 'Aug-20']]}) df = pd.DataFrame(df['data'].values, columns=df['columns']) # 初始化空画布,全局设置堆叠模式 fig = go.Figure(layout=go.Layout( xaxis = dict(title=dict(text='Casos Covid-19 Por Edad y Sexo: ',font=dict(size=18))), yaxis=dict(tickfont=dict(size=14)), barmode='stack' # 全局固定堆叠模式 )) # 获取排序后的月份列表 month_list = pd.DatetimeIndex(df['Fecha']).sort_values().unique() month_name_list = df['Mes-Año'].sort_values().unique() # 循环追加所有月份的trace for dt in month_list: df_FEM = df.loc[(pd.DatetimeIndex(df['Fecha']) == dt) & (df['Sexo'] == 'FEMENINO')] df_MAS = df.loc[(pd.DatetimeIndex(df['Fecha']) == dt) & (df['Sexo'] == 'MASCULINO')] # 追加女性trace fig.add_trace(go.Bar( x = df_FEM['Casos'], y = df_FEM['Edad'], orientation = 'h', name = 'FEMENINO', text = df_FEM['Casos'], texttemplate = '%{text:,9r}', textfont = {'size':18}, textposition ='inside', insidetextanchor ='middle' )) # 追加男性trace fig.add_trace(go.Bar( x = df_MAS['Casos'], y = df_MAS['Edad'], orientation = 'h', name = 'MASCULINO', text = df_MAS['Casos'], texttemplate = '%{text:,9r}', textfont = {'size':18}, textposition ='inside', insidetextanchor ='middle' )) # 构造滑块步骤 steps = [] total_trace = len(fig.data) # 总trace数 = 月份数 * 2 for idx in range(len(month_list)): # 每个月份对应2个trace,下标为idx*2 和 idx*2+1 visible = [False]*total_trace visible[idx*2] = True visible[idx*2 + 1] = True step = dict( method="update", args=[ {"visible": visible}, {"title": f"Casos Covid-19 Por Edad y Sexo: {month_name_list[idx]}"} ] ) steps.append(step) # 添加滑块配置 sliders = [dict( active=0, currentvalue={"prefix": "当前月份: "}, pad={"t": 50}, steps=steps )] fig.update_layout(sliders=sliders) # 默认显示第一个月的数据 fig.data[2:].visible = False fig.show()
核心修改点说明
- 提前初始化全局Figure对象,循环内仅使用
add_trace追加数据,不会覆盖之前的trace - 每个滑块步骤同时启用对应月份的2条trace(女性、男性),保证堆叠所需的两条数据同时可见
barmode='stack'全局设置在layout中,滑块切换时不会丢失堆叠配置- 滑块标题同步切换为对应月份名称,交互更友好
内容的提问来源于stack exchange,提问作者David YL
相关产品推荐
相关产品推荐

