I am trying to generate a plotly graph that the user can select the X and Y variables as well as the selected period [2020,2021]. So far I have constructed the following
but once I click the dropdowns, the legend is not taking effect any more so I am seeing all data and can not filter by year.
The code is the following:
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"}
)
as noted by @vestland using dash is the way to go. plotly dependent dropdowns are challenging.
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"}
)