2

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 Answer 1

2

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

Sign up to request clarification or add additional context in comments.

2 Comments

I would like to control each of the subplots individually. In other words, I would like to choose what to plot independently. For ex, on the 1st subplot I would like to plot stock1, but on the 2d - volatility for stock1. ( Imagine, if you have at least 20 graph for each of the Stocks)
I see. I'll try to figure out if there is a way to make my answer more generalizable.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.