How to dynamically show/remove secondary yaxis with custom buttons?

Hi there,

Can anyone tell me how to dynamically show/hide a secondary yaxis when button is changed. Iโ€™ve created a graph that graphs 2 different plots depending on the selected button. I want the secondary yaxis to be displayed on the first graph, but when I switch to Yearly I want y2 to be removed. The showticklabels:False argument was a workaround I thought would work. Anyone know how to do this?

# Create figure
fig = go.Figure()

# Add traces

fig.add_trace(
    go.Bar(x=list(df_q.index),
               y=list(df_q['Total']),
               name="Total Number",
               visible=True)
                )

fig.add_trace(
    go.Scatter(x=list(df_q.index),
               y=list(df_q['Performance (%)']),
               name="Performance",
               visible=True,
                mode="lines+markers",
                line=dict(color="#ffc000")))


fig.add_trace(
    go.Scatter(x=list(df_q.index),
           y=df_q['Performanc Target'],
           name="Target",
           visible=True,
           line=dict(color="red", dash="dash")))


fig.add_trace(
    go.Bar(x=list(df_year.index),
               y=list(df_year['Performance (%)']),
               name="Performance",
               visible=False,
               marker_color='lightsalmon'))

fig.add_trace(
    go.Bar(x=list(df_year.index),
               y=list(df_year['Performanc Target']),
               name="Target",
               visible=False,
               marker_color='indianred',
))

# Add dropdown
fig.update_layout(
    updatemenus=[
        go.layout.Updatemenu(
            active=0,
            buttons=list([
                dict(method='update',
                    args=[{"visible": [True, True, True, False, False, False]},
                          {'yaxis':{'ticksuffix': None}}],
                    label="Quarterly"
                ),
                dict(method='update',
                    args=[{"visible": [False, False, False, True, True, True]},
                         {'yaxis':{'ticksuffix': '%'}},
                         {'yaxis2':{'showticklabels': False}}],
                    label="Yearly"
                )
            ]),
            direction="down",
            pad={"l": 0, "t": -10},
            showactive=True,
            x=0.1,
            xanchor="left",
            y=1.1,
            yanchor="top"
        ),
    ]
)

fig.update_layout(
    showlegend=False
)

fig['data'][1]['yaxis'] = 'y2'
fig['data'][2]['yaxis'] = 'y2'

fig['layout']['yaxis2'] = {'anchor': 'free',
               'overlaying': 'y',
               'position': 1.0,
               'side': 'right',
               'ticksuffix': '%'}

Hi @KyleOS,

Welcome to Plotly forum! I read your question a few days ago, but since I wasnโ€™t able to define the button args such that to make the secondary axis invisible, I opened an issue on plotly.js, because the arg definition is less pythonic, and more javascript specific.
Here is a simplified version of your figure, with the right definition of the updatemenus: https://plot.ly/~empet/15494.

Hi @empet! Apologies for the delay in responding, only seeing this now. Your solution works perfectly. Thanks a million for the help!

1 Like

@empet Hello there, Iโ€™m fairly new to plotly and after tracking down your conversation with etpinard, Iโ€™m no closer to finding a workable solution within the framework my system uses. I feel like itโ€™s probably an issue outside of the specific one you and etpinard discussed. I would really appreciate any assistance.

Below is what I currently have within a Notebook. The data2 trace updates just fine, but nothing happens to yaxis2.

from plotly.offline import iplot


data = []
data.append({'x': [0,1,2,3],
             'y': [10,20,30,40],
             'name': 'data1',
             'showlegend': True})
data.append({'x': [0,1,2,3],
             'y': [40,30,20,10],
             'name': 'data2',
             'yaxis': 'y2',
             'showlegend': True,
             'visible': True})
layout = {'autosize': True,
          'title': 'Title',
          'xaxis': {'title': 'x-axis',
                    'zeroline': False,
                    'mirror': True},
          'yaxis': {'title': 'y-axis1',
                    'zeroline': False,
                    'mirror': True},
          'yaxis2': {'title': 'y-axis2',
                     'zeroline': False,
                     'mirror': True,
                     'anchor': 'free',
                     'overlaying': 'y',
                     'side': 'right',
                     'position': 1},
          'updatemenus': [{'buttons': [
                            {'args': [{'visible': [True, True]},
                                      {'yaxis2.visible': 'True'}],
                             'label': 'data2 On',
                             'method': 'update'},
                            {'args': [{'visible': [True, False]},
                                      {'yaxis2.visible': 'False'}],
                             'label': 'data2 Off',
                             'method': 'update'}],
                          'direction': 'down',
                          'showactive': True,
                          'xanchor': 'right',
                          'yanchor': 'top',
                          'x': .9,
                          'y': 1.3}],
          'legend': {'x': 0, 'y': 1, 'bgcolor': 'rgba(222, 222, 222, 0.5)'}}

fig = {'data': data, 'layout': layout}
iplot(fig)

edit: fixed formatting in the code block

@KyleOS

Your code doesnโ€™t work because in updatemenus:

'updatemenus': [{'buttons': [
                            {'args': [{'visible': [True, True]},
                                      {'yaxis2.visible': 'True'}],  #HERE must be True, NOT 'True'
                             'label': 'data2 On',
                             'method': 'update'},
                            {'args': [{'visible': [True, False]},
                                      {'yaxis2.visible': 'False'}],  #and HERE False, not `False`
                             'label': 'data2 Off',
                             'method': 'update'}]

you have quoted True and False, i.e.
{'yaxis2.visible': 'True'} , {'yaxis2.visible': 'False'}, instead of:
{'yaxis2.visible': True} and {'yaxis2.visible': False}

1 Like

Wow, thanks for that. Sometimes itโ€™s the simple things. Cheers!