plotly dash:创建多个回调(使用循环?

plotly dash: create multiple callbacks (with loop?)

提问人:jf328 提问时间:12/25/2018 最后编辑:jf328 更新时间:5/25/2020 访问量:13102

问:

假设我有一个包含 20 个参数的模型,我为每个参数制作了一个输入组件。

[dcc.Input(type = 'number', id = 'input %i'%i) for i in range(20)]

我想要一个按钮,它应该为所有输入填充最佳预拟合值。html.Button('populate parameters', id = 'button populate')

代码应如下所示,但它不起作用。

for i in range(20):
    @app.callback(
        dash.dependencies.Output('input %i'%i, 'value'),
        [dash.dependencies.Input('button populate', 'n_clicks')]
    )
    def update(ignore):
        return np.random.uniform()

我是否必须为每个具有相同功能的输出编写 20 个回调?我找不到一种方法可以一次性制作它们(循环?

plotly-dash

评论


答:

0赞 erkandem 12/25/2018 #1

您可以根据需要在回调上拥有任意数量的输入参数/参数。 但只有一个输出

为我解决类似案例的是:

@app.callback(
    [Output('output-id', 'children')],
    [Input('button-trigger', 'n_clicks'],
    [State('input-one', 'value'),
    ...
    [State('input-twenty', 'value')]
)
def my_fancy_function(n_clicks, v1, ..., v20):
    return sth_awesome

State()相反,当输入值发生更改时,不会触发回调。Input()

n_clicks每次点击都会更改 +1,但不需要使用。

如果参数相互依赖,则需要更多回调。 但。。。有 20 个参数There must be a better way

评论

0赞 jf328 12/25/2018
嗨,谢谢。我编辑了我的问题,以更清楚地表达我想要什么。一个输出约束是这里的问题。我有一个输入,但有 20 个输出。
1赞 erkandem 12/25/2018
也有类似的问题:我将结果转储到隐藏的 s 属性中,并使用 5 次回调读取该特定内容。这种方法使回调变得非常“简单”,因为所有 calback 都会听到它。jsonDivchildrenDivDiv
19赞 Shovalt 1/14/2019 #2

我已经处理了同样的问题并找到了解决方案。你要做的是绕过装饰器并直接调用该函数:app.callback

def update(ignore):
    return np.random.uniform()

for i in range(20):
    app.callback(
        dash.dependencies.Output('input %i' % i, 'value'),
        [dash.dependencies.Input('button populate', 'n_clicks')]
    )(update)
0赞 gustave toison 1/31/2019 #3

我做了一些类似的事情来在页面重新加载后填充我的布局组件。

由于第一次回调,组件的状态存储在 dcc.Store 组件中。 第二个回调是在布局组件的状态更改或访问选项卡时填充布局组件(布局位于 dcc.Tabs 中)

dash_layout_components = {
'time_slider_app2': 'value',
'backtest_choice_app2': 'values',
'asset_selection_app2': 'value',
'graph_selection_app2': 'values'
}

stored_layout_value_name = [key[:key.rfind('a')] + value for key, value in 
dash_layout_components.items()]

set_back_and_display_graph_input = {
    'store_layout_data': 'modified_timestamp',
    'tabs': 'value'
}


@app.callback(
Output('store_layout_data', 'data'),
[Input(key, value) for key, value in dash_layout_components.items()])
def store_layout(time_slider_value, backtest_choice_values, assets_selection_values, graph_selection_values):

    data_json = {
        'time_slider_value': time_slider_value,
        'backtest_choice_values': backtest_choice_values,
        'asset_selection_value': assets_selection_values,
        'graph_selection_values': graph_selection_values
   }
   return data_json


for component_id, component_property in dash_layout_components.items():
@app.callback(
    Output(component_id, component_property),
    [Input(key, value) for key, value in set_back_and_display_graph_input.items()],
    [State('store_layout_data', 'data'),
     State(component_id, 'id')]
)
def set_back_component(bouton_ts, tabs_value, layout_state_data, component):  # dynamiser l'arrivée des paramètres. piste, en créer une liste entre le for et le callback

    if tabs_value != '/app2':
        raise PreventUpdate

    if layout_state_data is None:
        return []

    else:
        store_layout_component_name = stored_layout_value_name[list(dash_layout_components.keys()).index(component)]
        return layout_state_data[store_layout_component_name]

请注意,您将无法访问函数 ( set_back_component(...) ) 中的迭代值 (component_id 和 component_property)

6赞 Niko Fohr 5/25/2020 #4

破折号 >= 1.11.0 中,您可以使用模式匹配回调。定义回调时不需要循环。

1. 导入回调选择器

  • 进口:dash.dependecies.ALL
from dash.dependencies import Input, Output, State, ALL
  • 其他可用的回调选择器包括 和 。MATCHALLSMALLER

2. 使用字典作为id

  • 使用字典定义组件。您可以选择任何键,但例如,并且是相当合理的选择。所以,而不是idtypeid
[dcc.Input(type = 'number', id = 'input %i'%i) for i in range(20)]

[
    dcc.Input(type='number',
              id={
                  'type': 'my-input-type',
                  'id': 'input %i' % i
              }) for i in range(20)
]

3. 将回调选择器与@app.callback

  • 定义回调时使用回调选择器:ALL
@app.callback(
    dash.dependencies.Output({
        'type': 'my-input-type',
        'id': ALL
    }, 'value'), [dash.dependencies.Input('button populate', 'n_clicks')])
def update(ignore):
    return np.random.uniform()