How do I use one legend filter to filter two graphs?

Hello,

I have two graphs displayed via the following code:

...ddk.Block(
        #width = 99,
        children=[
            ddk.ControlCard(
                [ddk.CardHeader(title="Item/Snapshot Dropdown"),
                ddk.ControlItem(children = [
        dcc.Dropdown(
            options = [{'label':i, 'value':i}
                 for i in items
                 ],
                multi=False,
                value = '100188K',
                id='item_dropdown',
        ),
        dcc.Dropdown(
            options = [{'label':i, 'value':i}
                 for i in snapshot
                 ],
                multi=False,
                value = '2021-01-31',
                id='snapshot_dropdown',
        ),
                ]
    )]
            ),
            ddk.Card(
                width=100,
                children =[
        ddk.Graph(
            id='snapshot_timeseries'
        ),
                ]),
        ddk.Card(
            width=100,
            children=[
        ddk.Graph(
            id='snapshot_timeseries_bias'
        )...
#CONTROL THE Time Series GRAPH
@callback(
    dash.dependencies.Output('snapshot_timeseries', 'figure'),
    dash.dependencies.Input('item_dropdown', 'value'),
)
def time_series_show_snapshot(item):
    df_table = df_final[df_final['ord_base7']==item].groupby(['ord_base7', 'item_desc','model', 'snapshot']).agg({'diff':'sum',
    'predicted_sales':'sum', 'sales_dollars':'sum'}).reset_index()
    df_table.loc[:, 'MAPE'] = np.round(df_table.loc[:, 'diff']/ df_table.loc[:, 'sales_dollars'], 4)
    df_table.loc[:, 'ACCURACY'] = 1 - df_table.loc[:,'MAPE']
    df_table.loc[:, 'BIAS'] = np.round((df_table.loc[:,'predicted_sales']- df_table.loc[:, 'sales_dollars'])/ df_table.loc[:, 'sales_dollars'], 4)
    # print("Data for time series", df_[['dmand_yr_mo', 'ord_base7', 'snapshot', 'model', 'location_type', 'sales_dollars']].sort_values('dmand_yr_mo'))
    
    fig = px.bar(df_table, x="snapshot", y="MAPE", 
                 color="model", barmode="group", title = "MAPE by Snapshot")
    return fig
#CONTROL THE Time Series GRAPH
@callback(
    dash.dependencies.Output('snapshot_timeseries_bias', 'figure'),
    dash.dependencies.Input('item_dropdown', 'value'),
)
def time_series_show_snapshot_bias(item):
    df_table = df_final[df_final['ord_base7']==item].groupby(['ord_base7', 'item_desc','model', 'snapshot']).agg({'diff':'sum',
    'predicted_sales':'sum', 'sales_dollars':'sum'}).reset_index()
    df_table.loc[:, 'MAPE'] = np.round(df_table.loc[:, 'diff']/ df_table.loc[:, 'sales_dollars'], 4)
    df_table.loc[:, 'ACCURACY'] = 1 - df_table.loc[:,'MAPE']
    df_table.loc[:, 'BIAS'] = np.round((df_table.loc[:,'predicted_sales']- df_table.loc[:, 'sales_dollars'])/ df_table.loc[:, 'sales_dollars'], 4)
    # print("Data for time series", df_[['dmand_yr_mo', 'ord_base7', 'snapshot', 'model', 'location_type', 'sales_dollars']].sort_values('dmand_yr_mo'))
    
    fig = px.bar(df_table, x="snapshot", y="BIAS", 
                 color="model", barmode="group", title = "BIAS by Snapshot")
    return fig

I would like to “click off” the models displayed in the legend in the upper graph, and have those same models “click off” in the lower graph. See below for current working app:

filter_action

Hi, maybe you could check the relayoutData, I’m not sure right now, if the legend click is part of it though

I checked this, it’s not the relayoutData but the restyleData. When selecting/deselecting the traces you’ll get something like this:

[
  {
    "visible": [
      true
    ]
  },
  [
    0
  ]
]

In this case I altered trace[0]. You can parse this dictionary and create a callback to alter the other graph. You could do this in a clientside callback or using the Patch() (Dash >= 2.9.0) for responsiveness.

Thank you. I will try to figure this out.

Hello) Did you manage to make it? I am having the same question…

Hey @M1sha welcome to the forums.

Here an MRE:

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

figure = go.Figure()

for i in range(4):
    figure.add_trace(
        go.Scatter(
            x=np.arange(1, 10),
            y=np.arange(1, 10) + 2 * i,
        )
    )

app = dash.Dash(__name__)

app.layout = html.Div(
    [
        dcc.Graph(
            id='graph_1',
            figure=figure

        ),
        dcc.Graph(
            id='graph_2',
            figure=figure
        ),
    ]
)


@app.callback(
    Output('graph_2', 'figure'),
    Input('graph_1', 'restyleData'),
    prevent_initial_call=True
)
def update(data):
    info, trace_list = data
    states = info['visible']

    patched = Patch()
    for state, trace in zip(states, trace_list):
        patched['data'][trace].update({'visible': state})
    return patched


if __name__ == "__main__":
    app.run(debug=True)

traces
mred patch