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

为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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.11 17:42:44