Black Lives Matter. Please consider donating to Black Girls Code today.

Dash interval updates issues

I created an Dash app with 2 heatmaps where it recomputes the value every second. I also have a checkbox core component at the top where it filters for which values to get heatmap for.

The issue is the checkbox defaults back to its default values whenever the graph updates.

Another issue is after a while, the graph doesn’t update anymore and the top of the browser still says “Updating…”

Here’s part of the code:

app.layout = html.Div(

html.Div([

dcc.Checklist(
id = ‘cl’,
options=[
{‘label’: “2017-12-08”, ‘value’: “2017-12-08”},
{‘label’: “2018-01-12”, ‘value’: “2018-01-12”},
{‘label’: “2018-02-09”, ‘value’: “2018-02-09”},
{‘label’: “2018-03-09”, ‘value’: “2018-03-09”}
],
values=[“2017-12-08”, “2018-01-12”, “2018-02-09”],
labelStyle={‘display’: ‘inline-block’}
),
dcc.Graph(id=‘example-graph1’, style={‘height’: “25%”}),
dcc.Graph(id=‘example-graph2’, style={‘height’: “25%”}),
dcc.Interval(
id=‘interval-component1’,
interval=1 * 1000 # in milliseconds
),
dcc.Interval(
id=‘interval-component2’,
interval=1 * 1000 # in milliseconds
),
])
)

def update_figure(time, label):
figure = {
‘data’: get_graph(time, label),
‘layout’: serve_layout()
}
return figure

@app.callback(dash.dependencies.Output(‘example-graph2’, ‘figure’),
events=[Event(‘interval-component2’, ‘interval’)])
def update_figure2():
figure2 = update_figure(30, “second”)
return figure2

@app.callback(dash.dependencies.Output(‘example-graph1’, ‘figure’),
events=[Event(‘interval-component1’, ‘interval’)])
def update_figure1():
figure = update_figure(5, “first”)
return figure

It looks like in analyzing the network through chrome it is fetching values for the heatmap it is just not displaying them…

What does your ''get_graph" function return? It should be a list of plotly trace objects. I have made this mistake in the past.

It works though without being a list?

It is also created through figure_factory.create_annotated_heatmap

figure_factory.create_annotated_heatmap returns a plotly figure object (dictionary). This is what should be returned by your update_figure function.

I’m having the same issue where all widgets return to default for every interval update. How did you end up fixing that?

Thanks!

Can you share a small, reproducable example?

@chriddyp - Here is a simple example of the issue i’m facing. The dropdown selection defaults back to ‘Choice 1’ after every interval.

gif_1

import dash
import dash_core_components as dcc
from dash.dependencies import Input, Output, State
import dash_html_components as html

app = dash.Dash(__name__)
server = app.server

app.layout = html.Div([
    dcc.Dropdown(
            id = 'variable_selected',
            options = [{'label':'Choice 1','value':1},
                        {'label':'Choice 2','value':2},
                        {'label':'Choice 3','value':3}],
            value=1
        ), ## this will default to 1 after every interval 
    dcc.Interval(id='update_interval', interval=2000, n_intervals=0),
    html.Div(id='output_example')
])

@app.callback(Output('output_example', 'children'), [Input('update_interval', 'n_intervals')])
def test(interval):
    return "The interval number is {}".format(interval)


if __name__ == '__main__':
    app.run_server(debug=True,port=8055)

Thank you! This looks like a bug. I’ll work on a fix now

OK, I see what the problem is. The component isn’t keeping its own state after the app gets refreshed.

Now, this particular case is uncommon because the dcc.Dropdown isn’t hooked up to any callback. If it was hooked up to a callback, you wouldn’t see the issue (after it is hooked up to a callback, Dash’s front-end maintains the components state, rather than the component itself. This means that when dash’s front-end rerenders the app, it will supply the correct value).

So for now, just connect all of your components. If you change your callback to be:

@app.callback(
    Output('output_example', 'children'),
    [Input('update_interval', 'n_intervals'),
     Input('variable_selected', 'value')])
def test(interval, value):
    return "The interval number is {} and the value is {}".format(
        interval, value
    )

then the issue should be fixed.

1 Like

Thanks! Appreciate the detailed response!

Thanks! This helped me also.

Maybe this behaviour isn’t clear in docs, or maybe I didn’t read out the right section (Live Updating Components).