1

The performance is breakingly slow when I pass hundreds of points to scattermapbox using plotly's dash, from sqlite query.

What is the best way to pass data to a scattermapbox in a dash application?

I've seen examples (https://github.com/plotly/dash-uber-rides-demo) with far more data points which are performing far better.

I am not sure if this is because of the data structure (nd.array, dataframe, sqlalchemy query results) or the interface used (graph_objs.scattermapbox vs dcc.graph).

Examples in Dash documentation pass data differently and use a different import/interface. dcc vs. graph_objs.

I am using dcc.graph, comprehension from query results:

s = session

surveys = s.query(Survey).all()
locations = [s.location for s in surveys if s.location]

figure = {
    'data': [
        {
            'type': 'scattermapbox',
            'lat': [l.lat],
            'lon': [l.lon],
            "mode": "markers",
        } for l in [s.location for s in surveys if s.location]
    ],
    'layout': {
        'mapbox': {...}
    }
}

app.layout = html.Div([
    dcc.Graph(
        id='map',
        figure=figure,
    )
])

# Remap based on zip of any clicked point
@app.callback(
    [Output('map', 'figure'),
     Output('click-data', 'children')],
    [Input('map', 'clickData'), Input('button', 'n_clicks')],
    # [State('dropdown', 'value')],
)
def on_click(clickData, n_clicks):
    data = clickData
    point = data['points'][0]

    # Use lat, lon to query the database
    loc = s.query(Location).filter((Location.lat == point['lat']) & (Location.lon == point['lon'])).first()
    locations = s.query(Location).filter(Location.zip == loc.zip)
    figure = {
        'data': [
            {
                'type': 'scattermapbox',
                'lat': [l.lat],
                'lon': [l.lon],
                "mode": "markers",
            } for l in locations
        ]
    }
    return figure

Expected results: Performance similar to the Uber rides dash example

Actual results: Map takes about 30 seconds to reload on new query

  • As a first step, you should check how much time is spend on the database call (inside the callback). This is the typical approach: https://stackoverflow.com/questions/7370801/measure-time-elapsed-in-python – emher Apr 24 '20 at 18:03

0 Answers0