Jupyter Notebook中基于图例选中状态动态更新柱状图总计值
解决Jupyter Notebook中Plotly双轴图图例联动更新总计柱状图的问题
在Jupyter Notebook环境下,无需依赖Dash,可通过Plotly的FigureWidget实现图例选中状态与总计柱状图的动态联动。核心思路是利用FigureWidget的事件监听能力,捕捉图例点击触发的restyle事件,实时计算选中系列的总和并更新柱状图数据。
完整实现代码
import plotly.graph_objects as go import pandas as pd import numpy as np # 生成测试数据 dates = pd.date_range(start='2024-01-01', periods=10) categories = ['A', 'B', 'C'] df = pd.DataFrame({ 'Date': dates.repeat(len(categories)), 'Category': np.tile(categories, len(dates)), 'Value': np.random.randint(10, 50, size=len(dates)*len(categories)) }) # 转换为宽格式方便绘图 df_wide = df.pivot(index='Date', columns='Category', values='Value') # 创建FigureWidget(关键:替代普通Figure) fig = go.FigureWidget() # 添加各分类折线图(左轴) for cat in categories: fig.add_trace(go.Scatter( x=df_wide.index, y=df_wide[cat], name=cat, yaxis='y1' )) # 计算初始总计并添加柱状图(右轴) total_initial = df_wide.sum(axis=1) fig.add_trace(go.Bar( x=df_wide.index, y=total_initial, name='总计', yaxis='y2', marker_color='gray', opacity=0.6 )) # 配置双轴布局 fig.update_layout( yaxis=dict(title='分类数值'), yaxis2=dict(title='总计数值', overlaying='y', side='right'), legend=dict(orientation='h', yanchor='bottom', y=1.02, xanchor='right', x=1) ) # 定义图例点击事件回调函数 def update_total(trace, points, state): # 获取当前所有折线trace(排除总计柱状图) line_traces = [t for t in fig.data if t.type == 'scatter'] # 获取每个折线的选中状态(visible属性) selected_mask = [t.visible == True or t.visible is None for t in line_traces] # 筛选出选中的分类数据 selected_data = df_wide.iloc[:, selected_mask] # 重新计算总计 new_total = selected_data.sum(axis=1) # 更新总计柱状图的y值 with fig.batch_update(): fig.data[-1].y = new_total # 为每个折线trace绑定restyle事件(图例点击会触发该事件) for trace in fig.data[:-1]: trace.on_restyle(update_total) # 在Notebook中显示图表 fig
关键细节说明
- 使用
FigureWidget而非普通Figure:FigureWidget是Plotly专为交互式环境设计的对象,支持实时事件监听和数据更新,这是实现联动的核心基础。 - 事件监听逻辑:图例点击会触发
restyle事件,我们为每个折线图trace绑定回调函数,在回调中:- 过滤出所有折线类型的trace(排除总计柱状图)
- 检查每个折线的
visible属性,判断是否被选中 - 基于选中的分类重新计算各时间点的总和
- 通过
batch_update()批量更新柱状图数据,提升交互流畅度
- 双轴配置:确保折线图使用左轴(
yaxis='y1'),柱状图使用右轴(yaxis='y2'),避免轴刻度冲突。
内容的提问来源于stack exchange,提问作者Daniel MB
相关产品推荐
相关产品推荐

