title: Plotly: How to toggle traces with a button similar to clicking them in legend?
body: <p>I'm using python and creating standalone html files with interactive plots (no Dash). I have been able to build a plotly plot with buttons that can toggle the visibility of traces in the plot. However, this functionality removes the traces from the legend as well. What I would like is to be able to keep the functionality of the legend (click a single trace to toggle visibility) but also have a set of buttons that extends that functionality to a group of traces that I define.</p>
  <p>The goal is to be able toggle everything (or a select group) to invisible but add individual items from that group back to visible as needed.</p>
  <p>Below is an example (using modified code from <a href="https://stackoverflow.com/questions/59406167/plotly-how-to-filter-a-pandas-dataframe-using-a-dropdown-menu/59406996#59406996">this answer</a> by vestland) to show what I am currently attempting.</p>
  <pre><code>import numpy as np
  import pandas as pd
  import plotly.graph_objects as go
  import datetime
  
  # mimic OP's datasample
  
  NPERIODS = 200
  
  np.random.seed(123)
  df = pd.DataFrame(np.random.randint(-10, 12, size=(NPERIODS, 4)),
                    columns=list('ABCD'))
  datelist = pd.date_range(datetime.datetime(2020, 1, 1).strftime('%Y-%m-%d'),
                           periods=NPERIODS).tolist()
  df['dates'] = datelist 
  df = df.set_index(['dates'])
  df.index = pd.to_datetime(df.index)
  df.iloc[0] = 0
  df = df.cumsum()
  
  # set up multiple traces
  traces = []
  buttons = []
  for col in df.columns:
      traces.append(go.Scatter(x=df.index,
                              y=df[col],
                              visible=True,
                              name=col)
                  )
      buttons.append(dict(method='update',
                          label=col,
                          visible=True,
                          args=[{'visible':[x == col for x in df.columns]}],
                          args2=[{'visible':[x != col for x in df.columns]}]
                          )
                  )
  
  # create the layout 
  layout = go.Layout(
      updatemenus=[
          dict(
              type='buttons',
              direction='right',
              x=0.7,
              y=1.3,
              showactive=True,
              buttons=buttons
          )
      ],
      title=dict(text='Toggle Traces',x=0.5),
      showlegend=True
  )
  
  fig = go.Figure(data=traces,layout=layout)
  
  # add dropdown menus to the figure
  fig.show()
  </code></pre>
  <p>That example does not work how I would like. Below is a screenshot of what it looks like at first.</p>
  <p><a href="https://i.stack.imgur.com/oJl79.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/oJl79.png" alt="stockplot" /></a></p>
  <p>The problem is that if I use one of those buttons, it does hide all the other traces but it also removes them from the legend so they can't be toggled back to visible.</p>
  <p><a href="https://i.stack.imgur.com/8livD.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/8livD.png" alt="onlyBvisible" /></a></p>
  <p>So my question becomes,  is there a different value in the args list/dictionary that can be given for the functionality to match that of simply clicking a trace in the legend?</p>
  <p>Sort of related, is there some way to get the current state of visibility for each trace?</p>