Skip to content
Advertisement

Python Dash – how to pass parameters in @app.callback

I am trying to create a Dash example that could make use of live updates by using the documentation here: https://dash.plotly.com/live-updates

In the code there is a key part which allows the app.call back to know what the input and output is:

@app.callback(Output('live-update-text', 'children'),
              Input('interval-component', 'n_intervals')

This works well for one component, however if say I have five different data sets to update (all using the same logic), then I would naturally hope to have the @app.callback to be passed in dynamically like a function parameter. i.e., ideally if I have 5 output I can do:

@app.callback(Output('live-update-text-MyParam', 'children'),
              Input('interval-component', 'n_intervals')

and then I can call it by using myParam = 1/2/3/4/5.

Is it possible?

UPDATE 20220105: Based on @coralvanda and @EricLavault’s suggestion this is what I came up with:

def updateGraphsAndData(output, input):
    @app.callback([output['text'],
                   output['graph']],
                  [input['n_intervals'],input['name']])
    def updateGraphAndMetricForEach(n, name):
        return update_metrics(name), update_graph_live(name)

for param in lstParams:
    updateGraphsAndData(output={'text':Output(f'live-update-text-{param}','children'),'graph':Output(f'live-update-graph-{param}','figure')},
                        input={'n_intervals':Input(f'interval-component-{param}','n_intervals'),'name':Input(param, 'value')})

I am trying to update both the graph and the text in one shot and the update_metrics is the update text part (returns a list of html.Span() and .Br()s) and the update_graph_live returns a go.Figure object).

However when I run this the page does not return any chart nor text to be updated, and clicking on the “callback” on the bottom right part, I see the children is pointed to null (even though I can see it is passed in as ‘live-update-text-PARAM’ and I can confirm update_metrics for valid inputs of name).

Is there still any place I am missing something?

UPDATE 20220106: Portion of app.layout code:

dbc.Col([
                html.Div(id=f'live-update-text-{param1}'),
                dcc.Graph(id=f'live-update-graph-{param1}'),
                dcc.Interval(
                id=f'interval-component-{param1}',
                interval=2*1000, # in milliseconds
                n_intervals=0
                ),
            html.Hr(),
            ], width={'size': 4, 'offset': 0, 'order': 1}),

And then this repeated for param1/param2/param3/param4/param5

Advertisement

Answer

The first issue I see is that you got multiple dcc.Interval (one per live component), but it’s not neccessary since you only need one call per interval for updating all the components.

Then, since all the elements to be updated are in the same container (I assume you put the dbc.Col in a dbc.Row) you can use a single output in your callback which updates the container children.

So in your layout you can do :

dcc.Interval(
    id='interval-component',
    interval=2*1000,  # in milliseconds
    n_intervals=0
),

dbc.Row(id="live-update-wrapper", children=[
    dbc.Col([
            html.Div(id=f'live-update-text-{param}'),
            dcc.Graph(id=f'live-update-graph-{param}'),
            html.Hr(),
        ],
        width={'size': 4, 'offset': 0, 'order': 1}
    ) for param in [1, 2, 3, 4, 5]
]),

And for the callback use the same logic (just grab the needed data and insert them accordingly along with the param id) :

@app.callback(
    Output("live-update-wrapper", "children"),
    Input("interval-component", "n_intervals"))
def updateGraphsAndData(n):
    return [
        dbc.Col([
                html.Div(id=f'live-update-text-{param}'),
                dcc.Graph(id=f'live-update-graph-{param}'),
                html.Hr(),
            ],
            width={'size': 4, 'offset': 0, 'order': 1}
        ) for param in [1, 2, 3, 4, 5]
]
User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement