简体   繁体   中英

Dash Plotly callback inputs (Updates on Page Load)

I'm new to Dash and I'm trying to figure out how to set Callback inputs. My Dash app has graphs that I want to dynamically update with new data on every page load (or refresh.) I don't want to do it through user interaction such as dropdown, radio button... To do so I have created hidden divs as callback inputs, but I'm not sure this is the proper way.

Is there any other approach that would be more suitable (or elegant) in this situation? Please let me know if there's something else in my code that needs to be changed.

This is my code:

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)

Thanks for any help on this matter.

If you only want to update the plots on page load / refresh, I would advise against any callbacks and instead directly load the figures.

This way, you can leave out all the hidden and intermediate values.

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM