相互依赖的绘图下拉按钮

Interdependent plotly dropdown buttons

我正在尝试生成一个绘图图,用户可以 select X 和 Y 变量以及 selected 期间 [2020,2021]。到目前为止,我已经构建了以下

但是单击下拉菜单后,图例不再生效,所以我看到了所有数据,无法按年份筛选。

代码如下:

button_x_list = []
button_y_list = []
colors = {"A": "red", "B": "blue", "C": "yellow"}
for col in colnames:
button_x_list.append(
    dict(
        method="update",
        label=col,
        visible=True,
        args=[
            {"x": [df[col]]},
            {"xaxis": {"title": col}},
            {"marker":{"color": list(df["status"].map(colors))}},
        ],
    )
)

button_y_list.append(
    dict(
        method="update",
        label=col,
        visible=True,
        args=[
            {"y": [df[col]]},
            {"yaxis": {"title": col}},
            {"marker":{"color": list(df["status"].map(colors))}},
        ],
    )
)


button_x_dict = dict(
    direction="down",
    showactive=True,
    xanchor="left",
    yanchor="top",
    visible=True,
    buttons=button_x_list,
    pad={"r": 15, "t": 10},
    x=0.27,
    y=1.07,
)

button_y_dict = dict(
    direction="down",
    showactive=True,
    xanchor="left",
    yanchor="top",
    visible=True,
    buttons=button_y_list,
    pad={"r": 15, "t": 10},
    x=0.5,
    y=1.07,
)


annotation_x = dict(
    text="X:",
    showarrow=False,
    x=0.25,
    y=1.05,
    xanchor="left",
    xref="paper",
    yref="paper",
    align="left",
    yanchor="top",
)
annotation_y = dict(
    text="Y:",
    showarrow=False,
    x=0.48,
    y=1.05,
    xanchor="left",
    xref="paper",
    yref="paper",
    align="left",
    yanchor="top",
)

data_2020= df[df.index.year==2020]
data_2021= df[df.index.year==2021]
fig = go.Figure(go.Scatter(x=data_2020["3"], y=data_2020["3"], mode="markers", marker={"color":df["status"].map(colors)},name="2020"))
fig.add_trace(go.Scatter(x=data_2021["3"], y=data_2021["3"], mode="markers", marker={"color":df["status"].map(colors)},name="2021"))

fig.update_layout(
    updatemenus=[button_x_dict, button_y_dict], annotations=[annotation_x, annotation_y],
    title="Test",
    xaxis={"title":"3"}, yaxis={"title":"3"}
)

正如@vestland 所指出的,使用 dash 是可行的方法。 plotly 依赖下拉菜单具有挑战性。

  • 已使用将两个变量()编码到两个下拉列表中的每一个的方法
  • 添加第三个下拉菜单和修改菜单可以完成,但会变成组合爆炸
import plotly.graph_objects as go
import pandas as pd
import numpy as np
import itertools

s = 300
colnames = list("3456")
dfa = pd.DataFrame(
    {
        **{"status": np.random.choice(["A", "B", "C"], s)},
        **{c: np.random.uniform(5 + int(c), 10 + int(c), s) for c in colnames},
    }
).set_index(pd.date_range("1-jul-2020", periods=s))

button_x_list = []
button_y_list = []
colors = {"A": "red", "B": "blue", "C": "yellow"}
for year, col in itertools.product(dfa.index.year.unique(), colnames):
    df = dfa.loc[dfa.index.year==year]

    button_x_list.append(
        dict(
            method="update",
            label=f"{year} {col}",
            visible=True,
            args=[
                {"x": [df[col]]},
                {"xaxis": {"title": col}},
                {"marker":{"color": list(df["status"].map(colors))}},
            ],
        )
    )

    button_y_list.append(
        dict(
            method="update",
            label=f"{year} {col}",
            visible=True,
            args=[
                {"y": [df[col]]},
                {"yaxis": {"title": col}},
                {"marker":{"color": list(df["status"].map(colors))}},
            ],
        )
    )


button_x_dict = dict(
    direction="down",
    showactive=True,
    xanchor="left",
    yanchor="top",
    visible=True,
    buttons=button_x_list,
    pad={"r": 15, "t": 10},
    x=0.27,
    y=1.07,
)

button_y_dict = dict(
    direction="down",
    showactive=True,
    xanchor="left",
    yanchor="top",
    visible=True,
    buttons=button_y_list,
    pad={"r": 15, "t": 10},
    x=0.5,
    y=1.07,
)


annotation_x = dict(
    text="X:",
    showarrow=False,
    x=0.25,
    y=1.05,
    xanchor="left",
    xref="paper",
    yref="paper",
    align="left",
    yanchor="top",
)
annotation_y = dict(
    text="Y:",
    showarrow=False,
    x=0.48,
    y=1.05,
    xanchor="left",
    xref="paper",
    yref="paper",
    align="left",
    yanchor="top",
)


fig = go.Figure(go.Scatter(x=dfa["3"], y=dfa["3"], mode="markers", marker={"color":dfa["status"].map(colors)}))
fig.update_layout(
    updatemenus=[button_x_dict, button_y_dict], annotations=[annotation_x, annotation_y],
    title="Test",
    xaxis={"title":"3"}, yaxis={"title":"3"}
)