vestland
vestland

Reputation: 61074

Plotly: How to update one specific trace using updatemenus?

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:

enter image description here

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:

enter image description here

And I'd really like to keep all unspecified 'y' and traces unchanged.

Thank you for any suggestions!

Upvotes: 4

Views: 9338

Answers (1)

nicolaskruchten
nicolaskruchten

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

Related Questions