Patch to set trace to visible True/False

I want to use the Dash Patch feature to show or hide a trace in the graph. Is there any way of achieving this? The graph has a dynamic number of traces, so I don’t think I can use the update() method, as I don’t have any way of knowing what the index of the trace is.

Hey,
you could just update the opacity of the trace via Patch().
To find the index you’re looking for you can use the figure object as a State of your callback and search for the trace within it.

1 Like

Hi @kiteme, do you want tho hide the trace completely, ie you don’t want to see it in the legend neither?

How do you identify the trace, does it have a name or something? You could use the Patch() in combination with update_traces(selector={'name': 'name_of_trace'}). You could also change the selector key & value to whatever you might need.

1 Like

Hey @AIMPED - yes I would like to be able to hide it completely, and yes identify by name
Can you please advise me on how to use Patch together with update_traces? I don’t see anything in the documentation for either. Thanks!

Hi @kiteme,

I might have been a bit too fast with my response. You are completely right. In order to use the Pactch() method, you’ll need to know beforehand, which trace you want to change, i.e. the index in the list.

Since you don’t know the index, the only solution to this I see rigth now is, to do what @Louis suggested- transfer the figure in a State(),search for the trace name in the figure object and return the Patch().

from dash import Dash, Input, Output, State, html, dcc, Patch
from dash.exceptions import PreventUpdate
import numpy as np
import plotly.graph_objects as go

app = Dash(
    __name__,
)

app.layout = html.Div(
    [
        html.Button(
            children="click",
            id="btn"
        ),
        dcc.Graph(
            id='graph',
            figure=go.Figure(
                data=[
                    go.Scatter(
                        x=np.arange(10),
                        y=np.random.randint(1, 10, size=10),
                        name=f'name_{i}',
                        mode='markers',
                        marker={'color': 'red'}
                    )
                    for i in range(5)
                ],
            )
        )
    ]
)


@app.callback(
    Output("graph", "figure"),
    Input("btn", "n_clicks"),
    State("graph", "figure"),
    prevent_initial_call=True
)
def toggle_modal(_, figure):
    traces = figure['data']

    idx = -1
    for idx, trace in enumerate(traces):
        if trace['name'] == 'name_1':
            break

    if idx != -1:
        patched = Patch()
        patched['data'][idx]['visible'] = False
        return patched
    else:
        raise PreventUpdate


if __name__ == '__main__':
    app.run(debug=True)
1 Like

Thank you for confirming and attaching the sample!
Hopefully, it will be possible to combine Patch with the selector option soon

1 Like

I really hope the next evolution of the Patch() method will be partial inputs to callbacks!

1 Like