Update dcc.Graph scattermapbox on interval

hi everyone,
My goal is to get a dcc.Graph to update on an interval. The dcc.Graph receives a type of scattermapbox in it’s data key through a callback that looks like this:

@app.callback(
Output('map-graph', 'figure'),
[Input('interval', 'n_intervals')]
)
def update_map(n):
    url = 'https://www.example.com/endpoint'
    resp = requests.get(url)
    resp_df = pd.DataFrame(resp.json())

    for datapoint in resp_df['attributes']:
        data_deque.append(datapoint)

    lat_list = []
    lon_list = []
    for item in data_deque:
        lat_list.append('{0:.2f}'.format(float(item['latitude'])))
        lon_list.append('{0:.2f}'.format(float(item['longitude'])))

    return {
        "data": [
            {
                "type":"scattermapbox",
                "lat": lat_list,
                "lon": lon_list,
                "hoverinfo": "text",
                "hovertext": [],
                "mode": "markers",
                "marker": {
                    "size": 20,
                    "opacity": 1,
                    "color":"green"
                },
                "showlegend": False
            }
        ],
        "layout": layout_map
    }

In the code above I make an http request to get some data. New data is constantly being exposed by the API that I’m calling so I have a python deque called (data_deque) that is continuously receiving new data as it comes in and discarding older data.

If I print(lat_list, lon_list) I get the coordinates in their respective arrays so I know that they’re changing.


Here’s what the rest of the app looks like:

app.layout = html.Div(
    [
        html.Div([
            html.Div(
                    [
                        html.Div(
                            [html.H2(id="total-items"), html.P("Total Items")],
                            id="example-id1",
                            className="container",
                        ),
                    ],
                    id="example-id2",
                    className="example-class1",
                ),
        ], id="example-id3", className="example-class2",
        )
        html.Div(
            [
                html.Div([
                    dcc.Graph(
                        id="map-graph",
                        config={'displayModeBar': False},
                        animate=True,
                        style={})
                    ], className="example-class3",
                ),
            ], className="example-class4",
        ),
        dcc.Interval(
            id='interval',
            interval=1*1000, # in milliseconds
            n_intervals=1
        ),
    ]
)

@app.callback(
    Output('total-items', 'children'),
    [Input('interval', 'n_intervals')]
)
def update_total_items(n):
    return html.Div("{}".format(total_items))

if __name__ == "__main__":
   ###
   ## I have code here that uses task.LoopingCall and threading to update global variable `total_items`   
   ###
    app.run_server(debug=True)

I want to make the points on the map change on every interval. When I run this, total-items DOES UPDATE on every interval, which is awesome! The map-graph however doesn’t update unless I do a page refresh.

I guess I’m wondering if either: A) There’s a logic error somewhere or B) if it’s possible to update a dcc.Graph that has a scattermapbox on an interval and not have to refresh the page?

thank you!

1 Like

FWIW, I am having a similar issue: https://community.plotly.com/t/layout-not-refreshing-after-dcc-intervals-triggers-callback-function/27684 where the callback function is being triggered on the correct interval but the layout isn’t refreshing without a page refresh.

1 Like

ok good to know. will let u know if i can get it to work. maybe Dash version related? I’m on 1.0.0 for dash and dash-core-components. thank you

I am using 1.1.1 for both

just curious if you found a resolution to this issue

It should work if you get rid of animate=True in ddc.Graph.

1 Like

You’re a savior! Kudos!