Color Bar on Choropleth Map not Updating

Ok, below is a summary layout of my code with an image of my output.

I have a graph component that gets populated as a Map of the United States showing States (plotly), or a map of the United States showing counties (plotly express), depending on which map type is selected by a radio button.

When you change the drop down selection (Pick a DC), the states or county map & associated color bar get updated. Everything is working fine EXCEPT the color bar for the States Map runs into an issue once you change the radio button from States to Counties and then back to States. Everything updates as it should, but the color bar for the States Map stops updating as I change the drop down selection. It never changes from the original State Maps Color bar from the first drop down selection.

The County Map color bar, however, updates correctly every time. It’s like the States Map color bar gets stuck (but the map still updates correctly).

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

..drop down to change map distributions
..radio button to select map type states or counties


@app.callback(Output('map','figure'),
              [Input('map-type','value'), <---radio button input
               Input('state_picker','value')]) <--- drop down input

Function Summary:
if map type == 'states' then create a dataframe of state counts and create a choropleth states map using plotly
elif map type == 'counties' then create a dataframe of county counts and create a geojson counties map using plotly express

Thanks for reporting! Any chance you could create a simple, reproducible example with some sample data? We’ve got some resources to sample data here: How to Get your Questions Answered on the Plotly Forum. That’d save our open source dev team some time when diagnosing the issue and getting a fix out.

app = dash.Dash()


state_options = []
for state in df['orig_state'].unique():
    state_options.append({'label':str(state)+" "+str(df[df['orig_state'] == state]['dest_state'].count())
                          +" Packages",'value':state})
    
app.layout= html.Div([
        
    html.Div([    
    dcc.Graph(id='map')
                    ],style={'width': '60%', 'float': 'left', 'display': 'inline-block'
                             }), #,'paddingRight':'30px'
                        
    html.Div([
    html.H3('Pick a DC',style={'textAlign': 'center'}),
    html.Hr(), ### Probably remove this html.Hr, but maybe use it somewhere else   
    dcc.Dropdown(id='state_picker',options=state_options,value=df['orig_state'].min())
        ],style={'width': '15%', 'float': 'right'}),
    
    html.Div([
    dcc.RadioItems(id='map-type',
    options=[
    {'label': 'States', 'value': 'States'},
    {'label': 'Counties', 'value': 'Counties'},
    ],
    value='States'
    )
    ]),
    

])

 
@app.callback(Output('map','figure'),
              [Input('map-type','value'),
               Input('state_picker','value')])
def update_graph(map_type,state):
    if map_type == 'States':
        filtered_df =df[df['orig_state'] == state]['dest_state'].value_counts().reset_index().rename(columns={'index':'dest_state','dest_state': 'count'})
        figure={
                'data': [go.Choropleth(
                    #colorscale = 'Cividis',
                    colorscale = 'ylorrd',
                    locations = filtered_df['dest_state'],
                    z = filtered_df['count'],
                    locationmode = 'USA-states',
                    text = filtered_df['dest_state'],   
                    hoverinfo = 'text+z',
                    marker = dict(line = dict(color = 'rgb(255,255,255)',width = 2)),
                    colorbar = {'title':"# of Packages"}) ### look for guide to move colorbar closer to map
                                    ],
                'layout': go.Layout(
                    #title='map',
                    margin={'l': 1, 'b': 1, 't': 1, 'r': 1},
                    height=500,                
                    geo = {'scope':'usa','showlakes':True,'lakecolor':'rgb(85,173,240)'},
                                   )


            }

        return figure
    elif map_type == 'Counties':
        df_fip =df[df['orig_state'] == state]['GEOID'].value_counts().reset_index().rename(columns={'index':'dest_fip','GEOID': 'count'})
        from urllib.request import urlopen
        import json
        with urlopen('https://raw.githubusercontent.com/plotly/datasets/master/geojson-counties-fips.json') as response:
            counties = json.load(response)

        figure = px.choropleth(df_fip, geojson=counties, locations='dest_fip', color='count',
                                   #color_continuous_scale="Viridis",
                                   color_continuous_scale="ylorrd",
                                   #range_color=(0, 12),
                                   #title='name', ### to have a visible title, need to use update_layout title with top margin 50
                                   scope="usa",
                                   labels={'count':'# of Packages'}
                                  )
        figure.update_layout(margin={"r":0,"t":0,"l":0,"b":0})


        # Outline Country and State borders (subunits are states)
        figure.update_geos(
        visible=False, resolution=110, scope="usa",
        showcountries=True, countrycolor="Black",
        showsubunits=True, subunitcolor="Black",
        subunitwidth=1)

        return figure



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

Ok, here you go. You can use copy and paste below to make a sample dataframe of the data that I am using and then copy and paste the code that I just posted two replies back.

If this is a bug, in the mean time, could someone provide a work around? Thanks!

df = pd.DataFrame.from_dict({'orig_state': {0: 'IL',
  1: 'TN',
  2: 'TN',
  3: 'TN',
  4: 'TN',
  5: 'TN',
  6: 'TN',
  7: 'IL',
  8: 'TN',
  9: 'IL',
  10: 'TN',
  11: 'TN',
  12: 'IL',
  13: 'TN',
  14: 'TN',
  15: 'TN',
  16: 'IL',
  17: 'IL',
  18: 'TN',
  19: 'TN',
  20: 'IL',
  21: 'TN',
  22: 'TN',
  23: 'TN',
  24: 'TN',
  25: 'TN',
  26: 'TN',
  27: 'TN',
  28: 'IL',
  29: 'TN',
  30: 'TN',
  31: 'IL',
  32: 'IL',
  33: 'IL',
  34: 'TN',
  35: 'IL',
  36: 'TN',
  37: 'TN',
  38: 'IL',
  39: 'IL',
  40: 'IL',
  41: 'IL',
  42: 'IL',
  43: 'TN',
  44: 'TN',
  45: 'TN',
  46: 'IL',
  47: 'TN',
  48: 'IL',
  49: 'TN'},
 'dest_state': {0: 'CA',
  1: 'CA',
  2: 'CA',
  3: 'CA',
  4: 'CA',
  5: 'CA',
  6: 'OR',
  7: 'OR',
  8: 'OR',
  9: 'AL',
  10: 'OK',
  11: 'OK',
  12: 'OK',
  13: 'NY',
  14: 'NJ',
  15: 'NJ',
  16: 'NJ',
  17: 'PA',
  18: 'OH',
  19: 'GA',
  20: 'GA',
  21: 'MI',
  22: 'MI',
  23: 'MI',
  24: 'MI',
  25: 'TN',
  26: 'TN',
  27: 'TN',
  28: 'TN',
  29: 'TN',
  30: 'TN',
  31: 'TN',
  32: 'TN',
  33: 'TN',
  34: 'TN',
  35: 'TN',
  36: 'TN',
  37: 'TN',
  38: 'TN',
  39: 'TN',
  40: 'TN',
  41: 'TN',
  42: 'TN',
  43: 'TN',
  44: 'TN',
  45: 'TN',
  46: 'TN',
  47: 'TN',
  48: 'TN',
  49: 'TN'},
 'dest_zip': {0: '95610',
  1: '95621',
  2: '95621',
  3: '95621',
  4: '95621',
  5: '95621',
  6: '97015',
  7: '97015',
  8: '97015',
  9: '35045',
  10: '74017',
  11: '74017',
  12: '74017',
  13: '14031',
  14: '07066',
  15: '07066',
  16: '07066',
  17: '18411',
  18: '43115',
  19: '30021',
  20: '30021',
  21: '48346',
  22: '48346',
  23: '48348',
  24: '48348',
  25: '37040',
  26: '37040',
  27: '37040',
  28: '37040',
  29: '37040',
  30: '37040',
  31: '37040',
  32: '37040',
  33: '37040',
  34: '37042',
  35: '37042',
  36: '37042',
  37: '37042',
  38: '37042',
  39: '37042',
  40: '37042',
  41: '37042',
  42: '37042',
  43: '37042',
  44: '37042',
  45: '37042',
  46: '37043',
  47: '37043',
  48: '37043',
  49: '37043'},
 'zip5': {0: '95610',
  1: '95621',
  2: '95621',
  3: '95621',
  4: '95621',
  5: '95621',
  6: '97015',
  7: '97015',
  8: '97015',
  9: '35045',
  10: '74017',
  11: '74017',
  12: '74017',
  13: '14031',
  14: '07066',
  15: '07066',
  16: '07066',
  17: '18411',
  18: '43115',
  19: '30021',
  20: '30021',
  21: '48346',
  22: '48346',
  23: '48348',
  24: '48348',
  25: '37040',
  26: '37040',
  27: '37040',
  28: '37040',
  29: '37040',
  30: '37040',
  31: '37040',
  32: '37040',
  33: '37040',
  34: '37042',
  35: '37042',
  36: '37042',
  37: '37042',
  38: '37042',
  39: '37042',
  40: '37042',
  41: '37042',
  42: '37042',
  43: '37042',
  44: '37042',
  45: '37042',
  46: '37043',
  47: '37043',
  48: '37043',
  49: '37043'},
 'ZCTA5': {0: '95610',
  1: '95621',
  2: '95621',
  3: '95621',
  4: '95621',
  5: '95621',
  6: '97015',
  7: '97015',
  8: '97015',
  9: '35045',
  10: '74017',
  11: '74017',
  12: '74017',
  13: '14031',
  14: '07066',
  15: '07066',
  16: '07066',
  17: '18411',
  18: '43115',
  19: '30021',
  20: '30021',
  21: '48346',
  22: '48346',
  23: '48348',
  24: '48348',
  25: '37040',
  26: '37040',
  27: '37040',
  28: '37040',
  29: '37040',
  30: '37040',
  31: '37040',
  32: '37040',
  33: '37040',
  34: '37042',
  35: '37042',
  36: '37042',
  37: '37042',
  38: '37042',
  39: '37042',
  40: '37042',
  41: '37042',
  42: '37042',
  43: '37042',
  44: '37042',
  45: '37042',
  46: '37043',
  47: '37043',
  48: '37043',
  49: '37043'},
 'GEOID': {0: '06067',
  1: '06067',
  2: '06067',
  3: '06067',
  4: '06067',
  5: '06067',
  6: '41005',
  7: '41005',
  8: '41005',
  9: '01021',
  10: '40131',
  11: '40131',
  12: '40131',
  13: '36029',
  14: '34039',
  15: '34039',
  16: '34039',
  17: '42069',
  18: '39129',
  19: '13089',
  20: '13089',
  21: '26125',
  22: '26125',
  23: '26125',
  24: '26125',
  25: '47125',
  26: '47125',
  27: '47125',
  28: '47125',
  29: '47125',
  30: '47125',
  31: '47125',
  32: '47125',
  33: '47125',
  34: '47125',
  35: '47125',
  36: '47125',
  37: '47125',
  38: '47125',
  39: '47125',
  40: '47125',
  41: '47125',
  42: '47125',
  43: '47125',
  44: '47125',
  45: '47125',
  46: '47021',
  47: '47021',
  48: '47021',
  49: '47021'}})

Sorry for the spam, but I found a work around solution. If I make both maps using plotly express, then the color bar updates correctly as I switch back n forth between counties and states.

So the bug has something to do with swapping maps between plotly and plotly express.

1 Like