Lizzzz90
Lizzzz90

Reputation: 125

Use Plotly updatemenu to hide/show trace data and corresponding yaxis

I have a plotly plot with 3 traces each on different y axis. Initially trace 'A' and its y axis will be visible and the other two traces and their axes are hidden. On clicking buttons from updatemenu, each trace should become visible along with its axis. Clicking on a button again should hide data+axis again. Problem is for method 'update' I should pass the visibility list of all the traces but I do not have their current values (after user clicks on a button); this means when user 'shows' a trace and tries to 'show' another trace, previous show is reset. With method 'restyle', I am able to change visibility of trace data but not the yaxis. Is there a proper way to achieve this using updatemenu? I cannot use Dash, I want to try and do this with just plotly.

Below is the code I tried.

import plotly.graph_objects as go

fig = go.Figure()

fig.add_trace(go.Scatter(
    x=[1, 2, 3],
    y=[4, 5, 6],
    name="A",
line=dict(color='#1f77b4')
))


fig.add_trace(go.Scatter(
    x=[2, 3, 4],
    y=[40, 50, 60],
    name="B",
    yaxis="y2",
    visible=False,
line=dict(color='#ff7f0e')
))

fig.add_trace(go.Scatter(
    x=[4, 5, 6],
    y=[40000, 50000, 60000],
    name="C",
    yaxis="y3",
    visible=False,
line=dict(color='#d62728')
))


# Create axis objects
fig.update_layout(
    xaxis=dict(
        domain=[0.3, 0.7]
    ),
    yaxis=dict(
        title="A",
        titlefont=dict(
            color="#1f77b4"
        ),
        tickfont=dict(
            color="#1f77b4"
        )
    ),
    yaxis2=dict(
        title="B",
        titlefont=dict(
            color="#ff7f0e"
        ),
        tickfont=dict(
            color="#ff7f0e"
        ),
        anchor="free",
        overlaying="y",
        side="left",
        position=0.15,
        visible=False
    ),
    yaxis3=dict(
        title="C",
        titlefont=dict(
            color="#d62728"
        ),
        tickfont=dict(
            color="#d62728"
        ),
        anchor="free",
        overlaying="y",
        side="left",
        position=0.05,
        visible=False
    )
)

btn1 = dict(method='update',label="A", args=[{"visible": [False, True, True]}, { "yaxis.visible": False}],
                                args2=[{"visible": [True, True, True]}, { "yaxis.visible": True}])
btn2 = dict(method='update',label="B", args=[{"visible": [True, False, True]}, { "yaxis2.visible": False}],
                                args2=[{"visible": [True, True, True]}, { "yaxis2.visible": True}])
btn3 = dict(method='update',label="C", args=[{"visible": [True, True, False]}, { "yaxis3.visible": False}],
                                args2=[{"visible": [True, True, True]}, { "yaxis3.visible": True}])

update_menu = []
update_menu.append(dict(showactive=True,
                        xanchor='left', yanchor='top', buttons=[btn1], y=0.75, x=1.05))
update_menu.append(dict(showactive=True,
                        xanchor='left', yanchor='top', buttons=[btn2], y=0.65, x=1.05))
update_menu.append(dict(showactive=True,
                        xanchor='left', yanchor='top', buttons=[btn3], y=0.55, x=1.05))

# add update menus to the figure
fig.update_layout(updatemenus=update_menu)
# adjust button type
for m in fig.layout.updatemenus:
    m['type'] = 'buttons'

# Update layout properties
fig.update_layout(
    title_text="multiple y-axes example",
    width=800,
)

fig.show()

Upvotes: 0

Views: 250

Answers (1)

Lizzzz90
Lizzzz90

Reputation: 125

I found the solution. Basically args should have params in the following order: dict of data attributes, dict of layout attributes followed by the trace indices to be modified.

btn1 = dict(method='update',label="A", args=[{'visible': False}, { "yaxis.visible": False }, [0]],
                            args2=[{'visible': True},{ "yaxis.visible": True }, [0]])

Upvotes: 0

Related Questions