plotly-dash - 回调的输出作为另一个回调的输入,第二个回调运行两次
问题描述
仪表板包括一个下拉列表、一个表格和一个图表。通过从下拉列表中选择一个项目,可以显示表格的一些行,并用图形绘制表格中的数据。我有两个回调,
at the first one:
input : dropdown
output: table
second one:
input: table
output: figure
所以第一个回调的输出是第二个回调的输入。
import dash
import dash_table
import pandas as pd
from copy import deepcopy
import plotly.graph_objects as go
import dash_core_components as dcc
import dash_html_components as html
import dash_bootstrap_components as dbc
from dash.dependencies import Input, Output
data = pd.DataFrame({"a": ["a1", "a2"],
"b": [1, 2]})
app = dash.Dash(
__name__,
external_stylesheets=[dbc.themes.BOOTSTRAP],
prevent_initial_callbacks=True,
)
app.layout = dbc.Container(
[
dbc.Row(dbc.Col([dcc.Dropdown(
id='dropdown1',
options=[
{'label': '1', 'value': 1},
{'label': '2', 'value': 2}
],
value=1)])),
dbc.Row(
dbc.Col([
dash_table.DataTable(
id="datatable",
columns=[dict(id=i,
name=j,
)
for i, j in zip(
["a", "b"],
["a", "b"],
)],
data=data.loc[data['a'] ==
"a1"].to_dict("records"),
sort_mode="single",
)
])),
dbc.Row([dbc.Col([html.Div(
children=dcc.Graph(id="graph"), className="card")
])]),
], fluid=True,
)
########################################################
@app.callback(
Output("datatable", "data"),
[Input("dropdown1", "value")],
prevent_initial_call=True
)
def update_current_table(value):
idx = int(value)
print(idx)
if idx == 1:
df = (data.loc[data["a"] == "a1"])
return df.to_dict("records")
else:
df = deepcopy(data.loc[data["a"] == "a2"])
return df.to_dict("records")
########################################################
@ app.callback(
Output('graph', 'figure'),
[Input("datatable", "derived_virtual_data"),
Input("dropdown1", "value")
],
prevent_initial_call=True
)
def update_figure(table, value):
df = pd.DataFrame(table)
print(df)
fig = go.Figure()
return fig
if __name__ == "__main__":
app.run_server(debug=True, port=8000)
这里的问题是回调运行两次:
a b
0 a1 1
a b
0 a2 2
并且第一次打印表的先前值这会导致我正在处理的主要代码中出现错误。
如何防止破折号两次运行回调?
我发现一些其他问题抱怨运行回调两次,但我找不到合适的解决方案。
解决方案
问题是您有两个输入用于运行两次的回调:
@ app.callback(
Output('graph', 'figure'),
[Input("datatable", "derived_virtual_data"),
Input("dropdown1", "value")
],
prevent_initial_call=True
)
def update_figure(table, value):
下拉列表更改,并触发此回调,但它也触发表更新。更新后的表会导致derived_virtual_data
再次触发此回调。您可以通过将下拉值State
改为 a 来解决此问题,如下所示:
@ app.callback(
Output('graph', 'figure'),
[Input("datatable", "derived_virtual_data")],
[State("dropdown1", "value"),]
prevent_initial_call=True
)
def update_figure(table, value):
编辑:在另一次通读中,您甚至不使用value
第二个输入中的下拉列表。完全删除它也可以:
@ app.callback(
Output('graph', 'figure'),
[Input("datatable", "derived_virtual_data")],
prevent_initial_call=True
)
def update_figure(table):
推荐阅读
- python - 如何在 python 日志记录模块中指定级别?
- python - 如何在模板 html django 中调用外键的字段
- asp.net - gitignore ASP.NET 解决方案的正确路径
- frama-c - 如何使用 Frama-C 证明这个 C is_power_of_2 函数?
- ios - SwiftUI 2 使用 fileImporter 将文件从 Files 应用程序移动到文档目录
- java - 如何在for循环中除以2(Java)
- python - 如何在 Pandas 数据框切片中使用 apply 来设置多列的值
- python - 如何在循环中使用参数分析方法?
- php - 从多个选择中添加多个帖子元键
- powerbi - DAX 计数另一行(在另一个表中)的计数小于 1 的行