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

问题描述 投票:0回答:1

我目前正在学习 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()

我期望获得根据指定年份过滤后的数据。

python callback plotly-dash
1个回答
0
投票

您正在尝试使用 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
数据表。

© www.soinside.com 2019 - 2024. All rights reserved.