Black Lives Matter. Please consider donating to Black Girls Code today.
Dash HoloViews is now available! Check out the docs.

Updating displayed points on Scattermap w/ Dropdown

Hey everyone, I’m brand new to plot.ly / dash and it seems like it’s going to be perfect for a project of mine! I’ve currently got a dashboard with a table / map. I have a dropdown working to update the table with a specific install crews outgoing jobs, but I’m unsure about how to go about updating the map to show the location of those jobs in the most efficient way / with best practice. Below is the code I have currently. I appreciate any and all tips!

Creating a list of crews for our dropdown.

crew_options = []
for crew in dff['Crew'].unique():
    crew_options.append({'label': str(crew), 'value': crew})

# Main app Layout
app.layout = html.Div([
    html.H1('Scheduled Installs'),
    html.Div(id='text-content'),
    html.H4('Crew Selector'),
    dcc.Dropdown(
        id='crews',
        options=crew_options,
        value=list(set(dff['Crew'][0])),
        multi=True),
    dcc.Graph(
        id='map',
        figure={
            'data': [{
                'lat': df['lat'],
                'lon': df['long'],
                'marker': {
                    'size': 8,
                    'opacity': 0.6
                },
                'type': 'scattermapbox'
            }],
            'layout': layout_map
        }),
    html.Div([
        dt.DataTable(
            rows=dff.to_dict('records'),
            columns=dff.columns,
            row_selectable=True,
            filterable=True,
            sortable=True,
            selected_row_indices=[],
            id='datatable')
    ],
        style=layout_table
    )
])

# Callbacks / Functionality


@app.callback(
    Output('datatable', 'rows'),
    [Input('crews', 'value')])
def update_selected_row_indices(crew):
    df_aux = dff.copy()

    # Crew filter
    df_aux = df_aux[df_aux['Crew'].isin(crew)]
    rows = df_aux.to_dict('records')
    return rows




if __name__ == '__main__':
    app.run_server(debug=True)
@app.callback(
    Output('map', 'figure'),
    [Input('crews', 'value')]
)
def update_map(crew):
    df_map = df.copy()
    # Crew filter
    df_map = df_map[df_map['Crew'].isin(crew)]
    return {
        'data': [{
            'lat': df_map['lat'],
            'lon': df_map['long'],
            'marker': {
                'color': 'rgb(0,0,0)',
                'size': 8,
                'opacity': 0.6
            },
            'type': 'scattermapbox'
        }],
        'layout': layout_map
    }

This did the trick. Is it possible / better to put this all in one callback? Seems like with this there’s some duplication going on

Hello and congrats for finding out how to use the callback :slight_smile:

Currently there is no way to put that in one callback if you want to modify two components inside the layout. At the moment, each callback must modify one and only one component in the layout.