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.