Plotly: How to add dropdown menu for every subplot?

Viewed 874

I need to create two subplots with a dropdown menu and title for each graph. (side-by-side comparison). In addition, I 'd like to have a shared y-axis.

As for now, I have only one dropdown menu that change both graphs.

The code is following: (note that a df consists of 2 columns and datetimeindex).


    import plotly.offline as py
    import plotly.graph_objs as go
    from plotly.offline import init_notebook_mode, iplot, plot
    from plotly import tools
    
    labels = ["Vol", "R"]
    
    
    fig = tools.make_subplots(rows=1, cols=2)
    
    trace1 = go.Scatter(x=df.index,
                             y=df['Stock1'].rolling(window=12).std(),
                             mode='lines'
                            )
    trace2 = go.Scatter(x=df.index,
                             y=df['Stock1'],
                             mode='lines'
                            )
    
    fig.append_trace(trace1, 1, 1)
    fig.append_trace(trace2, 1, 1)
    
    trace1 = go.Scatter(x=df.index,
                             y=df['Stock2'].rolling(window=12).std(),
                             mode='lines'
                            )
    trace2 = go.Scatter(x=df.index,
                             y=df['Stock2'],
                             mode='lines'
                            )   
    fig.append_trace(trace1, 1, 2)
    fig.append_trace(trace2, 1, 2)
    
    
    # Create buttons for drop down menu
    buttons = []
    for i, label in enumerate(labels):
        visibility = [i==j for j in range(len(labels))]
        button = dict(
                     label =  label,
                     method = 'update',
                     args = [{'visible': visibility},
                         {'title': label}])
        buttons.append(button)
    
    updatemenus = list([
        dict(active=-1,
             x=-0.15,
             buttons=buttons
        )
    ])
    
    fig['layout']['title'] = 'Title'
    fig['layout']['showlegend'] = False
    fig['layout']['updatemenus'] = updatemenus
    
    iplot(fig, filename='dropdown')

1 Answers

According to empet's helpful answer in the Plotly forum, the important thing to know is that the visible key has length equal to the total number of traces in fig.data.

In your case, you have four traces that correspond to Stock 1 (Vol), Stock 1 (R), Stock 2 (Vol) and Stock 2 (R) which is the order in which you added these traces. So we can create 4 buttons to toggle the visibility feature of each trace and pass them as a list to the updatemenus dictionary.

import numpy as np
import pandas as pd

import plotly.offline as py
import plotly.graph_objs as go
from plotly.offline import init_notebook_mode, iplot, plot
from plotly import tools

## recreate some random data
np.random.seed(42)
df = pd.DataFrame(data=np.random.randint(0,100,(365,2)), columns=['Stock1','Stock2'], index=pd.date_range(start='1/1/2019', end='12/31/2019'))

labels = ["Vol", "R"]


fig = tools.make_subplots(rows=1, cols=2)

trace1 = go.Scatter(x=df.index,
                         y=df['Stock1'].rolling(window=12).std(),
                         mode='lines'
                        )
trace2 = go.Scatter(x=df.index,
                         y=df['Stock1'],
                         mode='lines'
                        )

fig.append_trace(trace1, 1, 1)
fig.append_trace(trace2, 1, 1)

trace1 = go.Scatter(x=df.index,
                         y=df['Stock2'].rolling(window=12).std(),
                         mode='lines'
                        )
trace2 = go.Scatter(x=df.index,
                         y=df['Stock2'],
                         mode='lines'
                        )   
fig.append_trace(trace1, 1, 2)
fig.append_trace(trace2, 1, 2)


## visible key for traces are in the order you append them

button1 = dict(method='update', 
               args=[{"visible": [True, False, False, False] }], 
               label="Stock 1, Vol" )
button2 = dict(method='update', 
               args=[{"visible": [False, True, False, False] }], 
               label="Stock 1, R" )   
button3 = dict(method='update', 
               args=[{"visible": [False, False, True, False] }], 
               label="Stock 2, Vol" )
button4 = dict(method='update', 
               args=[{"visible": [False, False, False, True] }], 
               label="Stock 2, R" )   

updatemenus = list([
    dict(active=-1,
         x=-0.15,
         buttons=[button1, button2, button3, button4]
    )
])

fig['layout']['title'] = 'Title'
fig['layout']['showlegend'] = False
fig['layout']['updatemenus'] = updatemenus

iplot(fig, filename='dropdown')

enter image description here

Related