Python Dash - 如何在@app.callback中传递参数
Python Dash - how to pass parameters in @app.callback
我正在尝试创建一个可以使用实时更新的 Dash 示例,方法是使用此处的文档:https://dash.plotly.com/live-updates
在代码中有一个关键部分允许 app.call 返回知道输入和输出是什么:
@app.callback(Output('live-update-text', 'children'),
Input('interval-component', 'n_intervals')
这对于一个组件来说效果很好,但是如果说我有五个不同的数据集要更新(都使用相同的逻辑),那么我自然希望传入@app.callback动态地像一个函数参数。即,理想情况下,如果我有 5 个输出,我可以这样做:
@app.callback(Output('live-update-text-MyParam', 'children'),
Input('interval-component', 'n_intervals')
然后我可以使用 myParam = 1/2/3/4/5 调用它。
可能吗?
更新 20220105:根据@coralvanda 和@EricLavault 的建议,这是我想出的:
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')})
我正在尝试一次性更新图表和文本,update_metrics 是更新文本部分(return 是 html.Span() 和 .Br 的列表()s) 和 update_graph_live returns a go.Figure object).
然而,当我 运行 这个页面没有 return 任何图表或文本要更新时,点击右下角的“回调”,我看到 children 指向 null(即使我可以看到它作为 'live-update-text-PARAM' 传入并且我可以确认 update_metrics 名称的有效输入)。
还有什么地方我遗漏了什么吗?
更新 20220106:app.layout 代码部分:
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}),
然后重复 param1/param2/param3/param4/param5
我看到的第一个问题是您有多个 dcc.Interval
(每个实时组件一个),但这不是必需的,因为每个时间间隔只需要一个调用来更新所有组件。
然后,由于所有要更新的元素都在同一个容器中(我假设您将 dbc.Col
放在 dbc.Row
中),您可以在回调中使用单个输出来更新容器子项。
因此在您的布局中您可以这样做:
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]
]),
对于回调使用相同的逻辑(只需获取所需的数据并将它们与参数 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]
]
我正在尝试创建一个可以使用实时更新的 Dash 示例,方法是使用此处的文档:https://dash.plotly.com/live-updates
在代码中有一个关键部分允许 app.call 返回知道输入和输出是什么:
@app.callback(Output('live-update-text', 'children'),
Input('interval-component', 'n_intervals')
这对于一个组件来说效果很好,但是如果说我有五个不同的数据集要更新(都使用相同的逻辑),那么我自然希望传入@app.callback动态地像一个函数参数。即,理想情况下,如果我有 5 个输出,我可以这样做:
@app.callback(Output('live-update-text-MyParam', 'children'),
Input('interval-component', 'n_intervals')
然后我可以使用 myParam = 1/2/3/4/5 调用它。
可能吗?
更新 20220105:根据@coralvanda 和@EricLavault 的建议,这是我想出的:
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')})
我正在尝试一次性更新图表和文本,update_metrics 是更新文本部分(return 是 html.Span() 和 .Br 的列表()s) 和 update_graph_live returns a go.Figure object).
然而,当我 运行 这个页面没有 return 任何图表或文本要更新时,点击右下角的“回调”,我看到 children 指向 null(即使我可以看到它作为 'live-update-text-PARAM' 传入并且我可以确认 update_metrics 名称的有效输入)。
还有什么地方我遗漏了什么吗?
更新 20220106:app.layout 代码部分:
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}),
然后重复 param1/param2/param3/param4/param5
我看到的第一个问题是您有多个 dcc.Interval
(每个实时组件一个),但这不是必需的,因为每个时间间隔只需要一个调用来更新所有组件。
然后,由于所有要更新的元素都在同一个容器中(我假设您将 dbc.Col
放在 dbc.Row
中),您可以在回调中使用单个输出来更新容器子项。
因此在您的布局中您可以这样做:
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]
]),
对于回调使用相同的逻辑(只需获取所需的数据并将它们与参数 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]
]