Our Aim
We’re creating a time series plot in a Django app using dash/plotly. The data being plotted is read from a pandas dataframe which is first pre-processed written to a file, and then sent to the next page via POST request for the interactive dashboard. On updating the dataframe the new plot should be plotted on the dashboard.
Problem
Even though the data is changed the dashboard doesn’t updates. It still shows the plot for the previous dataframe saved in the file. Until or unless the django server is restarted it doesn’t updates. dcc.interval()
doesn’t do the trick, it also requires the server to be restarted even though you can see the dash app reply in the console log plus it removes the zoom in capability for a graph since, it refreshes the plot. The Django version in use is 2.2.9
Anyone who ever came across this? How can this be done?
Edit
In the code below at start we manipulate the dataframe to our adjusted needs, then the dashboad itself has multiple html.div()
which in turn each have their own dcc.graph()
component which don’t seem to update when the dataframes are updated.
Here’s our code for the dash app:
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output,State
import plotly.graph_objs as go
from django_plotly_dash import DjangoDash
import pandas as pd
import dash_table
from datetime import datetime
app = DjangoDash('chalao')
selected_df=pd.read_pickle(r'static/selected_df.pkl')
actual_df=pd.read_pickle(r'static/actual_prediction.pkl')
datatable_df=actual_df
datatable_df.reset_index(inplace=True)
datatable_df['START_DATETIME'] = datatable_df['START_DATETIME'].astype(str)
datatable_df['Transaction'] = datatable_df['Transaction'].round(decimals=-3)
datatable_df['Prediction'] = datatable_df['Prediction'] + 500
datatable_df['Prediction'] = datatable_df['Prediction'].round(decimals=-3)
datatable_df['START_DATETIME'] = datatable_df['START_DATETIME'].map(lambda x: x.lstrip('T00:00:00'))
app.layout = html.Div([
html.H1('Stock Ticker Dashboard'),
html.H1('Transaction Dashboard'),
html.Div([
html.H3('Select start and end dates:'),
dcc.DatePickerRange(
id='my_date_picker2',
min_date_allowed=selected_df.index.min(),
max_date_allowed=selected_df.index.max(),
start_date=selected_df.index.min(),
end_date=selected_df.index.max()
)
], style={'display':'inline-block'}),
dcc.Graph(
id='my_graph2',
figure={
'data': [
{'x': selected_df.index, 'y': selected_df.Transaction,'name':'Transaction'},
],
'layout': go.Layout(title='Actual Transaction Graph')
}
),
html.Div([
html.H3('Select start and end dates:'),
dcc.DatePickerRange(
id='my_date_picker',
min_date_allowed=actual_df.index.min(),
max_date_allowed=actual_df.index.max(),
start_date=actual_df.index.min(),
end_date=actual_df.index.max()
)
], style={'display':'inline-block'}),
dcc.Graph(
id='my_graph',
figure={
'data': [
{'x': actual_df.index, 'y': actual_df.Transaction,'name':'Transaction'},
{'x': actual_df.index, 'y': actual_df.Prediction,'name':'Prediction'}
],
'layout': go.Layout(title='Predicted Graph')
}
),
dash_table.DataTable(
id='table',
columns=[{"name": i, "id": i} for i in datatable_df.columns],
data=datatable_df.to_dict('records'),
sort_action='native',
filter_action='native',
export_format='csv',
style_cell={'textAlign': 'center', 'font-size' : '16px','width': '10px',
'overflow': 'hidden'
},
style_data_conditional=[
{
'if': {'row_index': 'odd'},
'backgroundColor': 'rgb(248, 248, 248)'
}
],
style_header={
'backgroundColor': 'rgb(230, 230, 230)',
'fontWeight': 'bold',
'font-size' : '20px'
}
)
])
def update_graph(start_date, end_date):
start = datetime.strptime(start_date[:10], '%Y-%m-%d')
end = datetime.strptime(end_date[:10], '%Y-%m-%d')
updated_df=actual_df
updated_df=updated_df[start:end]
fig = {
'data': [
{'x': updated_df.index, 'y': updated_df.Transaction,'name':'Transaction'},
{'x': updated_df.index, 'y': updated_df.Prediction,'name':'Prediction'}
],
'layout': {'title': 'Prediction Graph'}
}
return fig
@app.callback(
Output('my_graph2', 'figure'),
[Input('my_date_picker2', 'start_date'),
Input('my_date_picker2', 'end_date')]
)
def update_graph2(start_date, end_date):
start = datetime.strptime(start_date[:10], '%Y-%m-%d')
end = datetime.strptime(end_date[:10], '%Y-%m-%d')
updated_df=selected_df
updated_df=updated_df[start:end]
fig = {
'data': [
{'x': updated_df.index, 'y': updated_df.Transaction,'name':'Transaction'}
],
'layout': {'title': 'Actual Transaction Graph'}
}
return fig
and below is the call to the dash app in our Django html template:
<div class="container-fluid">
{% load plotly_dash %}
<h1>Home Page</h1>
<div class="{% plotly_class name='chalao' %}" style="height: 100%; width: 100%;">
{% plotly_app name='chalao' ratio=0.45 %}
</div>
<br>
{{ plot1 | safe }}
</div>
Any guidance and or suggestion is appreciated, thanks.