Hi All,
I am trying to do something that should be very simple, yet I get an error loading layout. I have narrowed it down to a problem which manifests when a callback is used to generate a slider, the value of that slider is then used in a callback to look up and display data with that value as an index.
I have made a simplified code to illustrate the issue:
This code creates a dropdown which offers a choice of two timebases (hour and day). It then creates a slider which is produced through a callback with timebase as an input. The slider will either have the range of the hour timebase, or the day timebase. That alone works. However, when a separate div is created to display what value has been chosen by the slider (when using the value of the slider as an index to look up a date in the data frame), the app breaks and says “error loading layout”.
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import pandas as pd
from datetime import datetime
app = dash.Dash()
application = app.server
app.config.supress_callback_exceptions = True # to passback callbacks
# two data sets with different timebases
idx_rangeh = [i for i in range(1000)]
hours = pd.DataFrame(pd.date_range(datetime(2017, 5, 1), periods=1000, freq='H'), index=idx_rangeh, columns=['date'])
idx_ranged = [i for i in range(100)]
days = pd.DataFrame(pd.date_range(datetime(2017, 5, 1), periods=100, freq='D'), index=idx_ranged, columns=['date'])
# make map layout
app.layout = html.Div([
# timebase dropdown
dcc.Dropdown(id='timebase',
options=[
{'label': 'Hourly', 'value': 'Hr'},
{'label': 'Daily', 'value': 'Day'}
],
value='Hr',
clearable=False
),
html.Div(id='slider-keeper'),
html.H4(id='slider-value', style={'fontSize': 24, 'display': 'inline-block', 'margin-top': '25px'})
],style={'width': '80%', 'margin-left': 'auto',
'margin-right': 'auto','textAlign': 'center','backgroundColor': '#b3b3b3'})
@app.callback(Output('slider-keeper', 'children'),
[Input('timebase', 'value')])
def update_slider(timebase):
if timebase == 'Hr':
maxval = hours.shape[0] - 1
elif timebase == 'Day':
maxval = days.shape[0] - 1
return dcc.Slider(
id='map-slider',
min=0,
max=maxval,
step=1,
value=0,
updatemode='drag'
)
@app.callback(Output('slider-value', 'children'),
[Input('timebase', 'value'),
Input('slider', 'value')])
def SliderText(timebase, idx):
if timebase == 'Hr':
val = (days['date'][idx]).strftime('%Y-%m-%d %H:%M')
elif timebase == 'Day':
val = (hours['date'][idx]).strftime('%Y-%m-%d %H:%M')
return '{} which is idx {}'.format(val, idx) # idx
if __name__ == '__main__':
application.run(debug=True, port=8080)
Do you guys see anything that might be wrong about this? If so, please explain what is breaking here, and what a better approach may be.
Thanks,
Troy