Search code examples
pythonplotly

How to modify a Plotly graph's layout using custom buttons


I am trying to create two buttons on a plotly graph object using updatemenus. On the button click I want to add a new title (which I can do) and add a new y-axis title. Adding the new y-axis title is where I am having problems. I for some reason can change the title of the graph on a button click but not the y-axis title even though I am passing both parameters to args in the same way.

Below is a working example

import plotly.offline as py
import plotly.graph_objs as go
import numpy as np
import pandas as pd

# sample data
np.random.seed(1)
df = pd.DataFrame(np.random.randint(100, size=(10,2)), columns=list('AB'))
df['Date'] = pd.date_range('2021-01-01', '2021-01-10')

# create two traces
traceA = go.Scatter(x=df['Date'], y=df['A'])
traceB = go.Scatter(x=df['Date'], y=df['B'], visible=False)
data = [traceA, traceB]

# create a new layout for each trace
traceA_layout = dict(title='Plot A', yaxis_title='Plot A yaxis')
traceB_layout = dict(title='Plot B', yaxis_title='Plot B yaxis') # change the plot B title and axis

# create two buttons for each plot
updatemenus = list([dict(type="buttons", showactive=True, active=0,
                         buttons=list([dict(label='Plot A', method='update',
                                            args=[{'visible': [True, False]},
                                                  traceA_layout]), # add layout to args
                                       
                                       dict(label='Plot B', method='update',
                                            args=[{'visible': [False, True]},
                                                  traceB_layout]), # add layout to args
                                      ]),
                        )
                   ])

# default layout
layout = dict(title='Plot A', title_x=.5, xaxis_title='Date',
              yaxis_title='Plot A y-axis', hovermode="x unified", 
              updatemenus=updatemenus)

# plot
fig = dict(data=data, layout=layout)
py.iplot(fig, filename='test')
# py.plot(fig, filename='test.html')

enter image description here

When I click on the "Plot B" button it changes the graph and title but not the y-axis title. Is there a way to change the y-axis title on a button click? Is it possible to update the y-axis title using buttons?

enter image description here


Solution

  • Your code seems to work if you define the two layout dictionaries directly in the arguments lists as shown below.

    import plotly.offline as py
    import plotly.graph_objs as go
    import numpy as np
    import pandas as pd
    
    # sample data
    np.random.seed(1)
    df = pd.DataFrame(np.random.randint(100, size=(10, 2)), columns=list('AB'))
    df['Date'] = pd.date_range('2021-01-01', '2021-01-10')
    
    # create two traces
    traceA = go.Scatter(x=df['Date'], y=df['A'])
    traceB = go.Scatter(x=df['Date'], y=df['B'], visible=False)
    data = [traceA, traceB]
    
    # create two buttons for each plot
    updatemenus = list([dict(
        type='buttons',
        showactive=True,
        active=0,
        buttons=list([
            dict(
                label='Plot A',
                method='update',
                args=[
                    {'visible': [True, False]}, 
                    {'title': 'Plot A', 'yaxis': {'title': 'Plot A yaxis'}}
                ]
            ),
            dict(
                label='Plot B',
                method='update',
                args=[
                    {'visible': [False, True]}, 
                    {'title': 'Plot B', 'yaxis': {'title': 'Plot B yaxis'}}
                ]
            ),
        ]),
    )])
    
    # default layout
    layout = dict(
        title='Plot A',
        title_x=.5,
        xaxis_title='Date',
        yaxis_title='Plot A yaxis',
        hovermode='x unified',
        updatemenus=updatemenus
    )
    
    # plot
    fig = dict(data=data, layout=layout)
    py.iplot(fig, filename='test')