链式回调未在 Plotly Dash 应用程序中执行的问题

Issue with chained callbacks not executing in Plotly Dash app

提问人:Constantine 提问时间:9/9/2023 最后编辑:John CollinsConstantine 更新时间:9/16/2023 访问量:57

问:

我目前正在学习达世币中的链式回调,但停滞不前。有更多经验的人是否能够审查提供的代码并识别我可能犯的任何错误?

我的目标是链接回调,以便一个回调(使用该函数)的输出作为另一个回调的输入。但是,似乎没有执行任何回调。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()

我希望获得已根据指定年份筛选的数据。

python 回调 plotly-dash

评论


答:

0赞 John Collins 9/16/2023 #1

您正在尝试使用 ID 更新输出,但您的 Dash 中没有具有该 ID 的元素。要在回调之间传输数据,可以使用 ,如下所示。db_dataapp.layoutdcc.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)

生成此应用功能:Screen shot recording of dash app demo

当单击“提交”按钮时,第一个回调将执行 ,根据给定年份筛选数据帧,并将结果存储在 .然后,第二个回调将获取此存储的数据,将其转换回 DataFrame,并使用筛选后的结果更新 DataTable。long_lasting_query()db_datatbl