I’m plotting a lot of points (~800,000) and two subplots using plotly go.Scatter.
When I run my app on the development server, everything renders fine and the plot looks good. But when I deploy the app on gcloud app engine I’m getting “error loading layout”.
The plot is constantly updating as we get more data from a real-time instrument so everything looked ok until recently when the error popped up. I assumed it had to do with the addition of more points because when I shorten the record by 50,000 points or so and try deploying the app again, it loads fine.
I tried using go.Scattergl instead and it also doesn’t work. Why would it load fine on the development server but not when I actually deploy the app?
My code looks like this:
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets, assets_folder='assets')
server = app.server
app.config.suppress_callback_exceptions = True
colors = {
'background': '#FFFFFF',
'text': '#000000'
}
fig = make_subplots(specs=[[{"secondary_y": True}]])
fig.add_trace(
go.Scatter({'x': tnode, 'y': xnode, 'type': 'line', 'line':dict(color='rgb(0,0,0)'), 'name': 'x-tilt'}), secondary_y=False
)
fig.add_trace(
go.Scatter({'x': tnode, 'y': tempnode, 'type': 'line', 'line':dict(color='rgb(179, 17, 0 )'), 'name': 'temperature','yaxis': 'y2'}), secondary_y=True
)
fig.update_xaxes(
range=[tnode[len(tnode)-1]-timedelta(days=7),tnode[len(tnode)-1]]
)
# Set y-axes titles
fig.update_yaxes(
title_text="Temperature (°C)",
color='rgb(179, 17, 0 )',
secondary_y=True,
fixedrange=True,
side='right',
range=[5,40]
)
fig.update_yaxes(
title_text="X-axis Tilt (degrees)",
secondary_y=False,
fixedrange=False,
side='left',
range=rangex
)
fig.update_layout(
font_size=20
)
fig.update_layout(legend=dict(
orientation="h",
yanchor="bottom",
y=1.02,
xanchor="right",
x=0.8
))
# Add range slider
fig.update_layout(
xaxis=dict(
rangeselector=dict(font_size=12,
buttons=list([
dict(count=7,
label="1w",
step="day",
stepmode="backward"),
dict(count=1,
label="1m",
step="month",
stepmode="backward"),
dict(count=6,
label="6m",
step="month",
stepmode="backward"),
dict(count=1,
label="1y",
step="year",
stepmode="backward"),
dict(step="all")
])
),
rangeslider=dict(
visible=True
),
type="date"
)
)
fig.update_layout(hovermode="x unified",hoverlabel=dict(font_size=16),height=600,autosize=True)
config = {'responsive': True}
fig.layout._config= config
# -------------------------- PROJECT DASHBOARD ---------------------------- #
app.layout = html.Div(style={'backgroundColor': colors['background']}, children=[
dcc.Graph(
id='beacons-0920',
figure=fig
)
])
@app.callback(
Output('beacons-0920', 'figure'),
Input('beacons-0920', 'relayoutData'),
State('beacons-0920', 'figure'),
prevent_initial_call=True
)
def update_graph(relOut, fig):
# calculate separately for xmin and xmax
if 'T' in fig['layout']['xaxis']['range'][0]:
xmin = dt.datetime.strptime(fig['layout']['xaxis']['range'][0],'%Y-%m-%dT%H:%M:%S')
elif '.' in fig['layout']['xaxis']['range'][0]:
xmin = dt.datetime.strptime(fig['layout']['xaxis']['range'][0],'%Y-%m-%d %H:%M:%S.%f')
else:
xmin = dt.datetime.strptime(fig['layout']['xaxis']['range'][0],'%Y-%m-%d %H:%M:%S')
if 'T' in fig['layout']['xaxis']['range'][1]:
xmax = dt.datetime.strptime(fig['layout']['xaxis']['range'][1],'%Y-%m-%dT%H:%M:%S')
elif '.' in fig['layout']['xaxis']['range'][1]:
xmax = dt.datetime.strptime(fig['layout']['xaxis']['range'][1],'%Y-%m-%d %H:%M:%S.%f')
else:
xmax = dt.datetime.strptime(fig['layout']['xaxis']['range'][1],'%Y-%m-%d %H:%M:%S')
# calculate range for y-axes
# find timestamps in tnode
irange = np.where(np.logical_and(tnode>=xmin, tnode<=xmax))[0]
ystd = np.nanstd(xnode[irange])
yrange = [np.nanmin(xnode[irange])-ystd,np.nanmax(xnode[irange])+ystd]
fig['layout']['yaxis']['range'][0] = yrange[0]
fig['layout']['yaxis']['range'][1] = yrange[1]
return fig
'''