Struggling to understand pattern matching callbacks

I am trying to get my graph to continuously update based on different inputs. I’m pretty positive I have to use pattern matching callbacks for this. Here is a snippet of my code and graph. They work separately but once I try to change a second, the first reverts back. Can anyone help? Thanks!

layout = html.Div([
      children=[

        # Graph area
        html.Div(
            className="div-app",
            id='div-app',
            loading_state={'is_loading': True},
            style={'margin': '0px 20px', 'padding': '0px 20px'},
            children=[
                dash_loading_spinners.Pacman(
                    fullscreen=True,
                    id='loading-whole-app'
                )]),      
         dbc.Container([
            dbc.Row([
                # Change the start date
                html.Div([
                    html.H5('Change Start Date'),
                    dmc.DatePicker(
                        id='new-start-date',
                        style={'width': '125px'},
                        maxDate=datetime.now().strftime("%Y-%m-%d"),
                        firstDayOfWeek="sunday",
                        inputFormat="MM/DD/YYYY",
                    ),
                    dbc.Button('Change',
                        id="new-start-button",
                        color='secondary', 
                        n_clicks = 0,
                        style={"width": "100px", "height": "40px", "margin-top": "20px"}),
                ],
                style={'display': 'flex', "justify-content": 'center', "align-items": 'baseline', 'gap': '25px', 'margin-bottom': '30px'}
                )
            ]),

            html.Hr(),

            # Offset the data
            dbc.Row([
                html.Div([
                    dcc.Checklist(
                        ['  Offset from first data point'],
                        id='offset-checkbox',
                        style={'font-size': '20px', 'font-weight': '600'}),
                    html.H5('or'),
                    html.H5('Custom Zero Baseline Offset:'),
                    dcc.Input(
                        id='offset-number',
                        type='number',
                        placeholder='Offset',
                        style={'width': "100px",}
                    ),
                    dbc.Button('Offset',
                        id="offset-button",
                        color='secondary', 
                        n_clicks = 0,
                        style={"width": "100px", "height": "40px",}),
                ],
                style={'display': 'flex', 'justify-content': 'center', 'gap': '25px', 'margin-bottom': '30px', 'align-items': 'baseline', 'margin-top': '20px'})
            ]),

])
]
])


# Callback for graph
@callback(
    Output('div-app', 'children'),
    Input('store', 'data'),
    Input('new-start-button', 'n_clicks'),
    State('new-start-date', 'value'),
    Input('offset-button', 'n_clicks'),
    State('offset-number', 'value')
)
def create_graph(
    data, 
    n_clicks_new_start, 
    new_start_date, 
    n_clicks_offset,
    offset_value
):
    logging.info('Graphing the Data')
    while True:
        df = pd.DataFrame(data['df'])

        # Reads the changed start date (if changed) and alters the dataframe
        if new_start_date:
            if ctx.triggered_id == 'new-start-button':
                new_date_index = df['MeasureDate'].searchsorted(f'{new_start_date}T00:00:00', side='right')
                kept_index = len(df.index) - new_date_index
                if kept_index >=1 and kept_index < 576:
                    return dash.no_update, dash.no_update, dash.no_update, not open_alert
                df = df.iloc[-(kept_index):]
        df.reset_index(inplace=True)

        # Offsets the data
        if offset_value:
            if ctx.triggered_id == 'offset-button': 
                if offset_value >= 0:
                    df['DeviationValue'] = df['DeviationValue'] - offset_value
                else:
                    df['DeviationValue'] = df['DeviationValue'] + offset_value

        # Graph creation
        fig = px.area(df, 
                    y='DeviationValue', 
                    title=f"Graph of {data['engine']}",
                    # color='Sign',
                    color_discrete_map={
                        'Positive': 'green',
                        'Negative': 'red'
                    },
                    labels={
                        "DeviationValue": 'Deviation',
                        'index': ''
                    },
                    custom_data=['MeasureDate', 'DeviationValue']
                    )

Hello @bpolasek,

For this, it doesnt seem like you are using a “pattern-matching” callback, as this would entail using an index id={'index':1, 'type':'myButton'}

To update your graph constantly, you can look into live updates, using the dcc.Interval:

From the looks of your code, it seems as if you are updating the dcc.Store and using that as a trigger, if that is the case, then you just need to return the figure each time the function is called. (No while loop) Using a while loop will just endlessly loop in the server without sending a response back to the client, as a result this will never update the client.

1 Like

Oh the while True was for a logging command. Which honestly wasn’t even working. I’ll take it out and try your suggestions.

And yeah I knew I haven’t implemented pattern matching yet, but I didn’t know if what I was trying to achieve needed it or not. I’ll also look into dcc.Interval.

1 Like