2

So consider the following plot with multiple y-axes (taken from here link)

import plotly.graph_objects as go
from plotly.subplots import make_subplots

# Create figure with secondary y-axis
fig = make_subplots(specs=[[{"secondary_y": True}]])

# Add traces
fig.add_trace(
    go.Scatter(x=[1, 2, 3], y=[40, 50, 60], name="yaxis data"),
    secondary_y=False,
)

fig.add_trace(
    go.Scatter(x=[2, 3, 4], y=[4, 5, 6], name="yaxis2 data"),
    secondary_y=True,
)

# Add figure title
fig.update_layout(
    title_text="Double Y Axis Example"
)

# Set x-axis title
fig.update_xaxes(title_text="xaxis title")

# Set y-axes titles
fig.update_yaxes(title_text="<b>primary</b> yaxis title", secondary_y=False)
fig.update_yaxes(title_text="<b>secondary</b> yaxis title", secondary_y=True)

fig.show()

Is there anyway to get the axes to 'hide' and 'un-hide' as we click and unclick 'yaxis data' and 'yaxis2 data'? I need to construct a plot with more than 2 y-axes, and I would like the axes to 'hide' and 'unhide' as the user clicks the respective curve. Thanks for any help/guidance.

7
  • are you open to using dash? it's straight forward where callbacks can be used Commented Oct 28, 2021 at 9:57
  • Hi Rob.. Yes, I'd be open to using dash. How do I apply the app you created below with the fig creation above? Thanks for your help Commented Oct 28, 2021 at 12:17
  • I've updated answer to include figure creation as well. didn't answer this way because figure creation code obscures the core of the answer and is just a copy paste of your code Commented Oct 28, 2021 at 12:22
  • ah ok.. I tried running it this way as well, but I get an AttributeError: 'DummyMod' object has no attribute 'startswith' Problem seems to be with app = JupyterDash(name) Commented Oct 28, 2021 at 12:30
  • update: issue is with databricks.. got it to run in vs code no problem.. thanks Rob! Commented Oct 28, 2021 at 12:37

1 Answer 1

4
import dash
from dash.dependencies import Input, Output, State
from jupyter_dash import JupyterDash
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import numpy as np

# build a figure with defined number of traces, each trace using it's own yaxis
TRACES = 9
fig = go.Figure(
    [
        go.Scatter(
            x=np.linspace(0, 10, 10),
            y=np.random.uniform(1 * 10 ** y, 5 * 10 ** y, 10),
            name=str(y),
            yaxis=f"y{'' if y==0 else y+1}",
        )
        for y in range(TRACES)
    ]
).update_layout(
    {
        f"yaxis{'' if ax==0 else ax+1}": {
            "position": 1 - (ax / 20),
            "overlaying":None if ax==0 else "y",
        }
        for ax in range(TRACES)
    }
)
# some space for all the y-axes
fig = fig.update_layout(xaxis={"domain": [0, 0.4]})

# Build App
app = JupyterDash(__name__)
app.layout = dash.html.Div(
    [
        dash.dcc.Graph(id="fig", figure=fig),
    ],
)

@app.callback(
    Output("fig", "figure"), Input("fig", "restyleData"), State("fig", "figure")
)
def graphClick(clickData, fig):
    if not clickData:
        raise dash.exceptions.PreventUpdate
    yax = {
        f"yaxis{'' if tn==0 else tn+1}": {
            "visible": clickData[0]["visible"][i] != "legendonly"
        }
        for i, tn in enumerate(clickData[1])
    }
    return go.Figure(fig).update_layout(**yax)


# Run app and display result inline in the notebook
app.run_server(mode="inline")
Sign up to request clarification or add additional context in comments.

Comments

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.