Hello,
I have a somewhat large dash app and it is getting slow to update. I have a bunch of controls that all modify how a central graph/plot is displayed. The problem is that each time I modify one of the controls, the plot updates like 100 times instead of just once.
My controls are linked to each other in multiple layers. For example, I am making 1D plots and you can choose which x to plot against and the min/max values of x. If you change which x you want to plot, the min/max inputs get updated to relevant values for that x. Then the plot is re-created.
As a small example, consider this app:
app = dash.Dash()
# function to plot
def func(x):
return x[:,0]**2 + np.sin(x[:,1])
# default ranges for x0 & x1
xranges = [[0,1], [-np.pi, np.pi]]
# dropdown to pick which x to plot against
xchooser = dcc.Dropdown(
id='xchooser',
options=[{'label':'x0', 'value':'0'},{'label':'x1', 'value':'1'}],
value='0')
# the user can also modify the ranges manually
minsetter = dcc.Input(id='minsetter', type='number', value=xranges[0][0])
maxsetter = dcc.Input(id='maxsetter', type='number', value=xranges[0][1])
app.layout = html.Div([
html.Div(xchooser, style={'width':'15%'}),
html.Div(['Min: ',minsetter,'Max: ',maxsetter]),
html.Div([dcc.Graph(id='trend_plot')], style={'width':'80%','float':'right'})
])
@app.callback(Output('minsetter','value'),[Input('xchooser','value')])
def set_min(xindex):
return xranges[int(xindex)][0]
@app.callback(Output('maxsetter','value'),[Input('xchooser','value')])
def set_max(xindex):
return xranges[int(xindex)][1]
@app.callback(Output('trend_plot','figure'),
[Input('xchooser','value'),Input('minsetter','value'),Input('maxsetter','value')])
def make_graph(xindex, xmin, xmax):
npt = 20
xgrid = np.zeros((npt,2))
xgrid[:,int(xindex)] = np.linspace(int(xmin), int(xmax), npt)
print 'Calling func!'
f = func(xgrid)
return Figure(data=[Scatter(x=xgrid[:,int(xindex)], y=f, mode='markers+lines')])
app.run_server()
Whenever I change the xchooser, the terminal output shows that the graph gets re-created twice instead of once:
Calling func!
127.0.0.1 - - [25/Jul/2017 15:26:11] "POST /_dash-update-component HTTP/1.1" 200 -
Calling func!
127.0.0.1 - - [25/Jul/2017 15:26:11] "POST /_dash-update-component HTTP/1.1" 200 -
With a more complicated app (more inputs & more layers), these extra evaluations pile up and make it quite slow. Is there a way to force Dash to only update the graph once everything else is done being updated? It seems like there could be a more efficient dependency tree walk.