首页 > 解决方案 > Dash Plotly 回调输入(页面加载更新)

问题描述

我是 Dash 的新手,我正在尝试弄清楚如何设置回调输入。我的 Dash 应用程序有图表,我想在每次页面加载(或刷新)时使用新数据动态更新。我不想通过用户交互来做到这一点,例如下拉菜单、单选按钮......为此我创建了隐藏divs 作为回调输入,但我不确定这是正确的方法。

在这种情况下,还有其他更适合(或更优雅)的方法吗?请让我知道我的代码中是否还有其他需要更改的内容。

这是我的代码:

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import pandas as pd
import plotly.graph_objs as go
import json
import plotly.express as px

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.config['suppress_callback_exceptions'] = True


data = [['Blue', 30], ['Red ', 20], ['Green', 60]]
df = pd.DataFrame(data, columns=['Color', 'Number'])
data1 = [['A', 10, 88], ['B ', 50, 45], ['C', 25, 120]]
df1 = pd.DataFrame(data1, columns=['Letter', 'Column1', 'Column2'])


def serve_layout():
    slayout = html.Div(children=[
        html.H1(children='Colors and Letters', style={'text-align': 'center'}),
        html.Div([
            html.Div(id='input-value', style={'display': 'none'}),

            html.Div(id='intermediate-value', style={'display': 'none'}),
        ]),
        html.Div([dcc.Graph(id='graph', style={'width': 1200,
                                               "margin-left": "auto",
                                               "margin-right": "auto",
                                               }),
                  dcc.Graph(id='graph1', style={'width': 1200,
                                                "margin-left": "auto",
                                                "margin-right": "auto",
                                                })]),
        ])
    return slayout


@app.callback(Output('intermediate-value', 'children'),
              [Input('input-value', 'value')])
def clean_data(value):
    df_1 = df
    df_2 = df1
    datasets = {
        'df_1': df_1.to_json(orient='split', date_format='iso'),
        'df_2': df_2.to_json(orient='split', date_format='iso')
    }
    return json.dumps(datasets)


@app.callback(
    Output('graph', 'figure'),
    [Input('intermediate-value', 'children')])
def update_graph(cleaned_data):
    datasets = json.loads(cleaned_data)
    dff = pd.read_json(datasets['df_1'], orient='split')
    fig = go.Figure(data=[go.Bar(x=dff['Color'], y=dff['Number'], text=dff['Number'], textposition='auto')],
                    layout=go.Layout())
    return fig


@app.callback(
    Output('graph1', 'figure'),
    [Input('intermediate-value', 'children')])
def update_graph(cleaned_data):
    datasets = json.loads(cleaned_data)
    dff1 = pd.read_json(datasets['df_2'], orient='split')

    fig1 = px.line(x=dff1['Letter'], y=dff1['Column1'], color=px.Constant('Column1'),
                   labels=dict(x='Letter', y='Column1', color='Letter'))
    fig1.add_bar(x=dff1['Letter'], y=dff1['Column2'], name='Column2')
    return fig1


app.layout = serve_layout

if __name__ == '__main__':
    app.run_server(debug=True)

感谢您对此事的任何帮助。

标签: pythonplotly-dash

解决方案


如果您只想在页面加载/刷新时更新图表,我建议您不要使用任何回调,而是直接加载数据。

这样,您可以省略所有隐藏值和中间值。

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import pandas as pd
import plotly.graph_objs as go
import json
import plotly.express as px
import numpy as np

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.config['suppress_callback_exceptions'] = True


def refresh_data():
    data = [['Blue', 30], ['Red ', np.random.random(1)[0] * 10], ['Green', 60]]
    df = pd.DataFrame(data, columns=['Color', 'Number'])
    data1 = [['A', 10, 88], ['B ', 50, 45], ['C', 25, 120]]
    df1 = pd.DataFrame(data1, columns=['Letter', 'Column1', 'Column2'])
    return df, df1


def serve_layout():
    plot_style = {'width': 1200,
                  "margin-left": "auto",
                  "margin-right": "auto",
                  }
    slayout = html.Div(children=[
        html.H1(children='Colors and Letters', style={'text-align': 'center'}),
        html.Div(
            [dcc.Graph(figure=get_graph(), id='graph', style=plot_style),
             dcc.Graph(figure=get_graph1(), id='graph1', style=plot_style)]),
    ])
    return slayout


def get_clean_data():
    df_1, df_2 = refresh_data()
    datasets = {
        'df_1': df_1.to_json(orient='split', date_format='iso'),
        'df_2': df_2.to_json(orient='split', date_format='iso')
    }
    return json.dumps(datasets)


def get_graph():
    datasets = json.loads(get_clean_data())
    dff = pd.read_json(datasets['df_1'], orient='split')
    fig = go.Figure(data=[
        go.Bar(x=dff['Color'], y=dff['Number'], text=dff['Number'],
               textposition='auto')],
                    layout=go.Layout())
    return fig


def get_graph1():
    datasets = json.loads(get_clean_data())
    dff1 = pd.read_json(datasets['df_2'], orient='split')

    fig1 = px.line(x=dff1['Letter'], y=dff1['Column1'],
                   color=px.Constant('Column1'),
                   labels=dict(x='Letter', y='Column1', color='Letter'))
    fig1.add_bar(x=dff1['Letter'], y=dff1['Column2'], name='Column2')
    return fig1


app.layout = serve_layout

if __name__ == '__main__':
    app.run_server(debug=True)

推荐阅读