为DataFrame多级索引各层级创建Plotly下拉菜单
为多级索引DataFrame实现分层下拉筛选的Plotly交互式图表
针对你需要为多级索引的每个层级单独创建下拉菜单、且要导出为HTML文件的需求,这里提供基于Plotly Graph Objects的实现方案,完全不需要依赖Dash或ipywidgets:
核心思路
- 为多级索引的每个层级单独创建一个
updatemenus组件(下拉菜单) - 每个下拉菜单的按钮对应层级内的唯一值,通过
restyle方法控制对应trace的可见性 - 支持多下拉联动筛选,最终导出的HTML文件保留完整交互能力
完整代码实现
import numpy as np import pandas as pd import plotly.graph_objects as go # 生成模拟数据(多级索引列:日期+类别) categories = pd.Index(["A", "B"]) dates = pd.date_range(start="2026-01-01", end="2026-01-10", freq="D") columns = pd.MultiIndex.from_product([dates, categories], names=["Date", "Category"]) index = pd.Index(range(6), name="Observations") x, y, z = (pd.DataFrame( np.random.standard_normal(size=(len(index), len(columns))), columns=columns, index=index ) for _ in range(3)) # 创建3D散点图,每个(date, category)对应一个trace fig = go.Figure() trace_map = {} # 用于映射(date, category)到trace索引 for idx, (date, cat) in enumerate(columns): fig.add_scatter3d( x=x[date, cat], y=y[date, cat], z=z[date, cat], mode="markers", name=f"{date:%Y-%m-%d} | {cat}", visible=True # 默认显示所有点 ) trace_map[(date, cat)] = idx # -------------------------- # 创建日期层级下拉菜单 # -------------------------- date_buttons = [] # 添加"显示全部"按钮 date_buttons.append(dict( label="所有日期", method="restyle", args=[{"visible": [True]*len(columns)}] )) # 为每个日期创建按钮 for date in dates: # 筛选该日期对应的所有trace索引 matching_traces = [trace_map[(d, c)] for d, c in columns if d == date] # 生成可见性数组:匹配的trace显示,其余隐藏 visible = [idx in matching_traces for idx in range(len(columns))] date_buttons.append(dict( label=f"{date:%Y-%m-%d}", method="restyle", args=[{"visible": visible}] )) # -------------------------- # 创建类别层级下拉菜单 # -------------------------- cat_buttons = [] # 添加"显示全部"按钮 cat_buttons.append(dict( label="所有类别", method="restyle", args=[{"visible": [True]*len(columns)}] )) # 为每个类别创建按钮 for cat in categories: matching_traces = [trace_map[(d, c)] for d, c in columns if c == cat] visible = [idx in matching_traces for idx in range(len(columns))] cat_buttons.append(dict( label=f"类别 {cat}", method="restyle", args=[{"visible": visible}] )) # 配置布局,添加两个下拉菜单 fig.update_layout( updatemenus=[ # 日期下拉菜单(顶部左侧) dict( type="dropdown", x=0.1, y=1.15, xanchor="left", yanchor="top", showactive=True, buttons=date_buttons ), # 类别下拉菜单(顶部右侧) dict( type="dropdown", x=0.9, y=1.15, xanchor="right", yanchor="top", showactive=True, buttons=cat_buttons ) ], title="多级索引分层筛选3D散点图", scene=dict( xaxis_title="X值", yaxis_title="Y值", zaxis_title="Z值" ) ) # 保存为HTML文件(保留交互功能) fig.write_html("multi_index_scatter.html") fig.show()
关键细节说明
- trace映射表:用
trace_map字典记录每个多级索引元组对应的trace索引,方便快速筛选目标trace - 联动筛选:两个下拉菜单独立工作,选择日期后可以再选择类别,实现组合筛选(比如只显示2026-01-01的类别A数据)
- HTML导出:
fig.write_html()直接生成静态HTML文件,无需额外服务器,打开即可使用所有交互功能 - 性能优化:相比遍历所有元组生成单个下拉,分层下拉的按钮数量等于各层级唯一值数量之和,层级元素越多,优势越明显
内容的提问来源于stack exchange,提问作者Louis-Amand
相关产品推荐
相关产品推荐

