我目前正在学习 Dash 中的链式回调,但正在停滞。有更多经验的人是否能够检查所提供的代码并找出我可能犯的任何错误?
我的目标是链接回调,以便一个回调(使用
long_lasting_query()
函数)的输出作为另一个回调的输入。然而,似乎没有任何回调被执行。
import argparse
import dash_bootstrap_components as dbc
import pandas as pd
from dash import Dash, Input, Output, State, dcc, html
from dash.dash_table import DataTable
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(
description="Dash example",
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
parser.add_argument(
"-a",
"--addr",
type=str,
metavar="arg",
required=True,
help="address to bind to (ip:port)",
)
parser.add_argument("--debug", action="store_true", help="run in debug mode")
args = parser.parse_args()
return args
def long_lasting_query() -> pd.DataFrame:
df = pd.read_csv(
"https://raw.githubusercontent.com/plotly/datasets/master/gapminder_unfiltered.csv"
)
return df
columns = ["country", "continent", "year", "lifeExp", "pop", "gdpPercap"]
app = Dash(
external_stylesheets=[dbc.themes.BOOTSTRAP], suppress_callback_exceptions=True
)
app.layout = dbc.Container(
[
html.P(
"Year: ",
style={"display": "inline-block", "margin-right": "8px"},
),
dcc.Input(id="year", type="number", min=0),
html.Button("Submit", id="submit-val", n_clicks=0),
DataTable(
columns=[{"name": c, "id": c} for c in columns],
id="tbl",
page_size=20,
sort_action="native",
style_header={
"textAlign": "center",
},
),
]
)
@app.callback(
Output("db_data", "value"),
Input("submit-val", "n_clicks"),
State("year", "value"),
prevent_initial_call=True,
)
def load_data(n_clicks, value):
df = long_lasting_query()
df = df[df["year"] == value]
if df.empty:
return "{}"
return df.to_json(orient="split")
@app.callback(
Output("tbl", "data"),
Input("db_data", "value"),
)
def update_table(value):
df = pd.read_json(value, orient="split")
if df.empty:
return "{}"
return df.to_dict("records")
def main() -> None:
args = parse_args()
host, port = args.addr.split(":")
app.run(host=host, port=port, debug=args.debug)
if __name__ == "__main__":
main()
我期望获得根据指定年份过滤后的数据。
您正在尝试使用 ID
db_data
更新输出,但 Dash app.layout
中没有具有该 ID 的元素。要在回调之间传输数据,您可以使用 dcc.Store
,如下所示。
以下代码,
import dash
from dash import Input, Output, State
from dash import dcc, html
import dash.dash_table as dt
import dash_bootstrap_components as dbc
import pandas as pd
def long_lasting_query() -> pd.DataFrame:
df = pd.read_csv(
"https://raw.githubusercontent.com/plotly/datasets/master/gapminder_unfiltered.csv"
)
return df
columns = ["country", "continent", "year", "lifeExp", "pop", "gdpPercap"]
app = dash.Dash(
external_stylesheets=[dbc.themes.BOOTSTRAP],
suppress_callback_exceptions=True,
)
app.layout = dbc.Container(
[
html.P(
"Year: ",
style={"display": "inline-block", "margin-right": "8px"},
),
dcc.Input(id="year", type="number", min=0),
html.Button("Submit", id="submit-val", n_clicks=0),
dt.DataTable(
columns=[{"name": c, "id": c} for c in columns],
id="tbl",
page_size=20,
sort_action="native",
style_header={"textAlign": "center",},
),
dcc.Store(id="db_data"),
],
style={"margin": "10%"},
)
@app.callback(
Output("db_data", "data"),
Input("submit-val", "n_clicks"),
State("year", "value"),
prevent_initial_call=True,
)
def load_data(n_clicks, value):
if not value:
return {}
df = long_lasting_query()
df = df[df["year"] == value]
return df.to_dict("records")
@app.callback(
Output("tbl", "data"), Input("db_data", "data"),
)
def update_table(data):
if not data:
return []
df = pd.DataFrame(data)
return df.to_dict("records")
if __name__ == "__main__":
app.run(debug=True)
单击“提交”按钮时,第一个回调将执行
long_lasting_query()
,根据给定年份过滤数据帧,并将结果存储在 db_data
中。然后,第二个回调将获取此存储的数据,将其转换回数据帧,并使用过滤后的结果更新 tbl
数据表。