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

Trace not updating when switching from Scattermapbox to Choroplethmapbox

Hi I am currently on an app to create custom map visualisation.

I create a graph based on a file uploaded by the user and then would like to allow the user to choose in what way to display the data.

It all kind of works except that when switching from Scattermapbox to Choroplethmapbox, the trace on the figure does not update. If I then manually change the map style then the trace updates:

Does someone have an idea of where this could come from?

I’m experiencing the same issue with my maps. Did you managed come up with something on this?
@RenaudLN

@botivegh- Could you share a simple, reproducable example? Could you also share which versions of dash and dash_core_components you are using?

@chriddyp - I’m using the latest dash (1.9.0) and dcc (1.8.0).
I just noticed, if I take out the dcc.Loading element, it is working fine.
Anyway, here is a simple sample code.

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
from dash.exceptions import PreventUpdate
import pandas as pd 
import plotly.graph_objs as go
import plotly.express as px
 
df = pd.read_csv('./assets/data/test_map_data.csv')
##FILTER OUT THE CLOSED STORES
df[['Lat','Lon']] = df.coordinates.str.split(",",expand=True,)
df['Lat'] = pd.to_numeric(df['Lat'])
df['Lon'] = pd.to_numeric(df['Lon'])

external_stylesheets = ["https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"]
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

app.layout = html.Div([
    html.H2('Map Test', style={'textAlign' : 'center' }, className='page-title'),
    html.Div(id='page-content', children=[
            html.Div(html.Div([ html.H4('Map', className='chart-title'),
                                html.Div([html.Label('Select:', className='my-dropdown-label'),
                                dcc.Dropdown(id='banner-selector', multi=True,
                                                options=[{'label' : i , 'value' : i} for i in df['Fascia'].unique()],
                                                value=[] , 
                                                placeholder='All Selected')],
                                className='my-chart-dropdown'),
                                dcc.Loading(dcc.Graph(id='selected-map'), style={'verticalAlign':'middle','height' : '400px', 'paddingTop' : '175px'}, color='#FB7332', type='default')],
                                            className='chart-card'),
                            className='col-lg-6 col-md-12'),
    ])
])
#########
@app.callback(Output(component_id='selected-map', component_property='figure'),
                [Input(component_id= 'banner-selector', component_property='value')])
def update_pos_map(banner_value):
    px.set_mapbox_access_token(MAPBOX-API-KEY)
    if len(banner_value) > 0:
        df_mod = df[df['Fascia'].isin(banner_value)]
        fig = px.scatter_mapbox(df_mod, lat="Lat", lon="Lon", mapbox_style='light',color='Fascia' , zoom=2, height=400,hover_name='Fascia')
    else:
        fig = px.scatter_mapbox(df, lat="Lat", lon="Lon", mapbox_style='light',color='Fascia' , zoom=2, height=400, hover_name='Fascia')
    fig.update_traces(marker=dict(size=8))
    fig.update()
    return fig

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

Data looks like this:

link to gif showing the issue:

@botivegh For me the solution was to pass the previous figure in the State of the callback and update the figure object before returning it instead of creating a new one in each callback.