Using Dash, I would like to make live updates of changing data.
I have read the docs at Live Updates | Dash for Python Documentation | Plotly and there are basically two options: 1) predefined intervals using dcc.Interval
, or (2) updates on page load, setting the App.layout to a function def serve_layout()
. I only want new data to be loaded when the user refreshes the page (using refresh button in the browser), not when one interacts with a dash core component such as a dropdown menu.
The provided code below shows an interactive lineplot, but upon pushing the refresh button it is unsuccessful at loading new data. My question is: what to do to make it load new data and update graphs everytime the refresh button is hit? Is this possible using the serve_layout() function?
The file df.csv is an entirely fictive simplification.
The object df looks like this:
A B C
x 2 2
x 4 8
y 1 9
y 4 10
y 5 6
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 datetime
import json
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.config['suppress_callback_exceptions']=True
df = pd.read_csv('/mydirectory/df.csv')
def serve_layout():
slayout = html.Div([
html.Div([
dcc.Dropdown(
id='dropdown',
options=[{'label': i, 'value': i} for i in ['x','y']],
value='x'
),
html.Div(id='intermediate-value'),
]),
html.Div([
dcc.Graph(
id='igraph1',
style={'width': 1200}
),
])
])
return slayout
## CALLBACKS
@app.callback(Output('intermediate-value', 'children'),
[Input('dropdown', 'value')])
def clean_data(nvalue):
df_1 = df[df['A'] == nvalue]
datasets = {
'df_1' : df_1.to_json(orient='split', date_format='iso'),
}
return json.dumps(datasets)
@app.callback(
Output('igraph1', 'figure'),
[Input('intermediate-value', 'children')])
def update_fig1(cleaned_data):
datasets = json.loads(cleaned_data)
dff = pd.read_json(datasets['df_1'], orient='split')
return {
'data' : [go.Scatter(
x=dff['B'],
y=dff['C'],
name='test',
marker={'size':10, 'opacity':0.5, 'line':{'width':2}}
)],
'layout' : go.Layout(
xaxis={'title':'Time'},
yaxis={'title':'Values'},
margin={'l':40, 'b':40, 't':40, 'r':0},
hovermode='closest'
)
}
app.layout = serve_layout
if __name__ == '__main__':
app.run_server(debug=True)
Thank you very much in advance for your time. Your help is very much appreciated !