How to set the values of args and args2 in Plotly's buttons in updatemenus?

Question:

I’m new to plotly and I am trying to understand how to set the values for args and args2 in the updatemenus functionality offered by plotly (as explained in the documentation Updatemenus documentation).

I tried to play with a code snippet I found in an answer here in stackoverflow (Plotly: How to give different label names in a dropdown menu?).

Here’s the modified code:

# imports
import plotly.graph_objects as go
import numpy as np

# data
x = np.linspace(-np.pi, np.pi, 100)

y1 = np.sin(x)
y1b = y1-1

y2 = np.tan(x)
y2b = y2-1

# plotly setup
fig = go.Figure()

# Add one ore more traces
fig.add_traces(go.Scatter(x=x, y=y1,name='sin', visible=False, showlegend=True))
fig.add_traces(go.Scatter(x=x, y=y1b,name='sin - 1', visible=False, showlegend=True))

fig.add_traces(go.Scatter(x=x, y=y2,name='tan', visible=False, showlegend=True))
fig.add_traces(go.Scatter(x=x, y=y2b,name='tan - 1', visible=False, showlegend=True))

# construct menus
updatemenus = [{'active':-1,'buttons': [{'method': 'restyle',
                             'label': 'Sine',
                             'args': [{'y': [y1, y1b, y2, y2b],
                                       'label':'Sine',
                                       'name':['sin', 'sin - 1', 'tan', 'tan - 1'],
                                       'visible': True}, [0, 1]],
                             'args2': [
                                       {'visible': False}, ]
                              },
                            
                            {'method': 'restyle',
                             'label': 'Tan',
                             'args': [{'y': [y2, y2b, y1, y1b],
                                       'name':['tan', 'tan - 1', 'sin', 'sin - 1'],
                                       'visible':True}, [0, 1]],
                             'args2': [{
                                       'visible':False},  
                                      ],
                             }
                           ],
                'direction': 'down',
                'showactive': True,}]

# update layout with buttons, and show the figure
fig.update_layout(updatemenus=updatemenus)
fig.show()

This gives me what I wanted to achieve that is to display the sine plots when I first click on Sine in the dropdown menu and clear the plot when I click again on Sine (and the same for Tan).

However, my problems are :

  • I can’t find any information in the documentation or anywhere else on what to pass to args and args2. Could you please provide any reference to documentation ?

  • At the end, I’m not even sure how to understand the behavior of args especially the first item (dictionary with ‘y’ and ‘name’ keys) and the second item with what I understand is a list of trace indices (?). In the following example, I set the list of indices to [2, 3] in the both Sine and Tan buttons. Therefore, I expect to have Tan plots by clicking on the Sine buttons and vice versa for the other button. But the plots do not change.


    # construct menus
    updatemenus = [{'active':-1,'buttons': [{'method': 'restyle',
                                 'label': 'Sine',
                                 'args': [{'y': [y1, y1b, y2, y2b],
                                           'label':'Sine',
                                           'name':['sin', 'sin - 1', 'tan', 'tan - 1'],
                                           'visible': True}, [2, 3]],
                                 'args2': [
                                           {'visible': False}, ]
                                  },
    
                                {'method': 'restyle',
                                 'label': 'Tan',
                                 'args': [{'y': [y2, y2b, y1, y1b],
                                           'name':['tan', 'tan - 1', 'sin', 'sin - 1'],
                                           'visible':True}, [2, 3]],
                                 'args2': [{
                                           'visible':False},  
                                          ],
                                 }
                               ],
                    'direction': 'down',
                    'showactive': True,}]

Could you please show me the correct way to set these values to target the right trace ?

Thank you in advance !

Asked By: Downforu

||

Answers:

1. Documentation

You can find info on args and args2 under buttons for updatemenus:

args Parent: layout.updatemenus[].buttons[] Type: list Sets the
arguments values to be passed to the Plotly method set in method on
click.

args2 Parent: layout.updatemenus[].buttons[] Type: list Sets a 2nd set
of args, these arguments values are passed to the Plotly method set
in method when clicking this button while in the active state. Use
this to create toggle buttons.

Admittedly, this is easier to find than to fully comprehend. The thing you should focus on first is Use this to create toggle buttons. Because that’s exactly what args2 is for; to provide a set of arguments that are set when a button is "not clicked". So buttons have several parameters:

  1. args: what happens when the button is clicked
  2. args2: what happens when it’s unclicked (to create toggle buttons)
  3. label: what is written on the button / label
  4. method: whether the button changes the plot, the layout or both

2. The correct way to set things up

The complete snippet below will show you how you can take the example that you’ve been running test on, and produce a figure that toggles between showing sine and tangent values for a few series.

Plot1 – Click button to get:

enter image description here

Plot 2 – Click button again to get:

enter image description here

If you take a closer look at the code below, you can see that I’ve set it up exactly as described in the documentation:

The first dict in args and args2 handles changes made to the traces / data:

{'y': [y1, y1b],
'name':['sin', 'sin - 1'],
'visible': True},

The second dict handles changes made to the layout of the figure:

{'title':'Sine'}

In the example below, it’s possible to edit both data and layout since method has been set to update.

The third element, a list, determines which traces changes should be made for:

[0, 1]

And one more important thing

What seemed to trigger the question Plotly: How to give different label names in a dropdown menu? is the fact that the label property of the button can’t be edited through the parameters in arg, and thus the functionality of the button, since both label and arg are exactly that; parameters of the button and not the figure object that the button controls. This becomes more apparent if you change the type attribute from button to dropdown. Now you can see that you’ll lose the label when the button is "unclicked" / dropdown option is unselected:

Plot 3:

enter image description here

And the only way to handle this is through adding another button if you’d like to emulate a toggle functionality for the button label, since the parameters in args or args2 are unable to "reach" that particular attribute of the button. I really hope someone is willing to prove me wrong on this one though, because these things often suddenly leave me a bit confused. But I hope that I’ve been able to make things a bit less confusing for you at least.

Complete code:

# imports
import plotly.graph_objects as go
import numpy as np

# data
x = np.linspace(-np.pi, np.pi, 10)

y1 = np.sin(x)
y1b = y1-1

y2 = np.tan(x)
y2b = y2-1

# plotly setup
fig = go.Figure()

# Add one ore more traces
fig.add_traces(go.Scatter(x=x, y=y1,name='sin', visible=True, showlegend=True))
fig.add_traces(go.Scatter(x=x, y=y1b,name='sin - 1', visible=True, showlegend=True))

fig.add_traces(go.Scatter(x=x, y=y2,name='tan', visible=False, showlegend=True))
fig.add_traces(go.Scatter(x=x, y=y2b,name='tan - 1', visible=False, showlegend=True))
fig.update_layout({'title' : 'Sine'})

# construct menus
updatemenus = [{
#                 'active':1,
                'buttons': [{'method': 'update',
                             'label': 'Toggle Sine / Tangent',
                             'args': [
                                      # 1. updates to the traces
                                      {'y': [y1, y1b],
                                       'name':['sin', 'sin - 1'],
                                       'visible': True}, 
                                      
                                      # 2. updates to the layout
                                      {'title':'Sine'},
                                      
                                      # 3. which traces are affected 
                                      [0, 1],
                                      
                                      ],
                             'args2': [
                                       # 1. updates to the traces  
                                       {'y': [y2, y2b],
                                       'name':['tan', 'tan - 1'],
                                       'visible':True},
                                      
                                       # 2. updates to the layout
                                       {'title':'Tangent'},
                                       
                                       # 3. which traces are affected
                                       [0, 1]
                                      ]
                              },
                            ],
                'type':'buttons',
#                 'type':'dropdown',
                'direction': 'down',
                'showactive': True,}]

# update layout with buttons, and show the figure
fig.update_layout(updatemenus=updatemenus)
fig.show()
Answered By: vestland
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.