Reputation: 61074
This is a follow-up question to Plotly: Plotly: How do the buttons for the update menus really work?
Consider the following plotly figure produced by the code snippet below:
Plot:
Code:
# imports
import plotly.graph_objs as go
import pandas as pd
import numpy as np
# data
df1 = pd.DataFrame({'index': ['1','2','3'], 'A': [10,10,12], 'B': [11,11,11]})
df2 = pd.DataFrame({'index': ['1','2','3'], 'A': [10,10,10], 'B': [11,11,12]})
# plotly figure setup
fig=go.Figure()
fig.add_trace(go.Scatter(x=df1['index'], y=df1['A'], mode='lines'))
fig.add_trace(go.Scatter(x=df1['index'], y=df1['B'], mode='lines'))
f=fig.to_dict()
#fig.show()
buttons=list([dict(args=[{'y':[df1['A'],df1['B']]}],
label="df1",
method="restyle"
),
dict(args=[{'y':[df2['A'], df2['B']]}],
label="df2",
method="restyle"
)
])
fig.update_layout(
updatemenus=[
go.layout.Updatemenu(
buttons=buttons,
direction="down",
pad={"r": 10, "t": 10},
showactive=True,
x=-0.25,
xanchor="left",
y=1,
yanchor="top"
),
]
)
fig.show()
In the snippet above, I'm updating the 'y'
values using buttons and dict(args=[{'y':[df2['A'], df2['B']]}]
. This assigns new values to both traces specified within the figure like this fig-to_dict
:
'data': [{'mode': 'lines',
'x': array(['1', '2', '3'], dtype=object),
'y': array([10, 10, 12], dtype=int64),
'type': 'scatter'},
{'mode': 'lines',
'x': array(['1', '2', '3'], dtype=object),
'y': array([11, 11, 11], dtype=int64),
'type': 'scatter'}]
Since I've assigned the list [df2['A'], df2['B']]
to 'y'
, plotly knows that I intend to update both instances of 'y'
in the snippet above. But within the context of buttons and update menus, is there a way I can specify which 'y'
to update (in other words: what specific trace or line).
If I assign only one reference (array or pandas dataframe in this case), both traces will show the same values. So changing the following part:
args=[{'y':[df2['A'], df2['B']]}]
...with this:
args=[{'y':[df2['A']]}]
... will produce the following plot upon clicking df2
:
And I'd really like to keep all unspecified 'y'
and traces unchanged.
Thank you for any suggestions!
Upvotes: 4
Views: 9338
Reputation: 27370
In the list you are passing to args
for each button
, you can add an integer after the dict to indicate which trace you want to update. For example the following will update the first trace only (i.e. the one at index=0)
buttons=list([dict(args=[{'y':[df1['A'],df1['B']]}, [0]], # note the `, [0]` here!
label="df1",
method="restyle"
),
dict(args=[{'y':[df2['A'], df2['B']]}, [0], # note the `, [0]` here!
label="df2",
method="restyle"
)
])
Upvotes: 10