Trouble updating plotly express chloropleth_mapbox using slider value

Hi,

I am having trouble updating a plotly express chloropleth mapbox with a slider value (in this case it is weeks) . Please see code below:

import dash
import dash_html_components as html
import dash_core_components as dcc
import plotly.graph_objects as go
import plotly.express as px
import pandas as pd
import numpy as np
from dash.dependencies import Input, Output, State
import pathlib
import json
#read data

DATA_PATH = pathlib.Path(__file__).parent.joinpath("data")
ASSET_PATH = pathlib.Path(__file__).parent.joinpath("assets")

df = pd.read_csv(DATA_PATH.joinpath('excess_deaths_uk_w51.csv'))
#list of LADs for graphs:
lads= df['Area_Name'].unique().tolist()
#df for chloropleth (without england and wales)
df_maps=df[~df['Area_Name'].isin(['Wales', 'England'])]
#list of lads for map:
areas= df_maps['Area_Name'].unique().tolist()
#create a week '53' row to represent the whole year
for l in areas:
    new_row = {'Area_Code': list(df_maps[df_maps['Area_Name'] == l]['Area_Code'])[0], 
               'Area_Name': l, 
              'Week_Number':53, 
               'reg_deaths_15':np.sum(df_maps[df_maps['Area_Name'] == l]['reg_deaths_15']),
               'reg_deaths_16':np.sum(df_maps[df_maps['Area_Name'] == l]['reg_deaths_16']), 
                'reg_deaths_17':np.sum(df_maps[df_maps['Area_Name'] == l]['reg_deaths_17']),
                'reg_deaths_18':np.sum(df_maps[df_maps['Area_Name'] == l]['reg_deaths_18']), 
                'reg_deaths_19': np.sum(df_maps[df_maps['Area_Name'] == l]['reg_deaths_19']),
       'avg_reg_deaths_15_19':np.sum(df_maps[df_maps['Area_Name'] == l]['avg_reg_deaths_15_19']),
        'reg_deaths_20': np.sum(df_maps[df_maps['Area_Name'] == l]['reg_deaths_20']), 
        'Excess_2020_from_avg':np.sum(df_maps[df_maps['Area_Name'] == l]['Excess_2020_from_avg']),
       'estimated_2019_pop': list(df_maps[df_maps['Area_Name'] == l]['estimated_2019_pop'])[0],
        'excess_deaths_per_100t_20': np.sum(df_maps[df_maps['Area_Name'] == l]['excess_deaths_per_100t_20'])}
    #append row to the dataframe
    df_maps = df_maps.append(new_row, ignore_index=True)
#VERY IMPORTANT: create a column in the df_maps that has the name 'lad17nm' which corresponds to the json file name:
df_maps['lad17nm']=df_maps['Area_Name']
df_maps['lad17cd']=df_maps['Area_Code']
#list of weeks:
weeks= df_maps['Week_Number'].unique().tolist()
# get geojson for the choropleth
with open(ASSET_PATH.joinpath('Local_Authority_Districts_(December_2017)_Generalised_Clipped_Boundaries_in_Great_Britain.geojson')) as f:
    const = json.load(f)
#initialise the app:

app = dash.Dash(__name__)
app.config.suppress_callback_exceptions = True

#define layout
app.layout = html.Div(className='ten columns div-for-charts bg-grey',
                             children=[
                                     html.H1(f'Excess deaths per week of 2020'),
                                     html.Div(
                                        id="slider-container",
                                        children=[
                                                html.P(
                                                id="slider-text",
                                                children="Drag the slider to change the week:"),
                                                dcc.Slider(
                                                    id="weeks-slider",
                                                    min=min(weeks),
                                                    max=max(weeks),
                                                    value=max(weeks),
                                                    marks={
                                                        str(w): {
                                                        "label": str(w),
                                                        "style": {"color": "#7fafdf", 'font-family':'Roboto'},} for w in weeks})
                                                        ]),
                                                        html.H3(f'Excess deaths in week {weeks}.', id='title_weeks'),
                                                        dcc.Graph(id='map', config={'displayModeBar': False}, animate=True)
                             ])


# Callback for map deaths
@app.callback(Output('map', 'figure'),
              [Input('weeks-slider', 'value')])
def update_map(selected_value):
    df=df_maps[df_maps['Week_Number'] == selected_value]
    figure=px.choropleth_mapbox(df, geojson=const, color="excess_deaths_per_100t_20", color_continuous_scale="Oryel",
                    locations='lad17cd', featureidkey="properties.lad17cd",labels={'excess_deaths_per_100t_20':'Excess deaths per 100,000'}, hover_name='lad17nm',
                    opacity=0.7, range_color=[-220, 280],
                   center={"lat": 53.329844, "lon": -0.12574}, mapbox_style="stamen-toner", zoom=6
                  )
    figure.update_layout(margin={"r":0,"t":0,"l":0,"b":0},
        template='plotly_dark',
        paper_bgcolor='rgba(0, 0, 0, 0)',
                #   margin={'b': 15},
        legend_title="Excess deaths per 100,000",
    font=dict(
        family="Roboto",
        size=20,
        color="grey"),
    # width=800,
    height=1000

)
    return figure


#callback map title    
@app.callback(Output('title_weeks', 'children'),
            [Input('weeks-slider', 'value')])
def update_map_title(selected_value):
    return f'Excess deaths in week {selected_value}.'


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

The text in the title of the map does change, however the chloropleth stays the same. I can’t really see what I am doing wrong, can anybody help, please?

Hi @anapengelly,

It’s difficult to help without the Dataframe, add a print(df) after the formula and see if it’s taking the information you neeed.

Hope it helps

1 Like

HI Eduardo, thanks for your reply!
So you mean in the callback, in the update_map function?

I did that and I get the correct df, every time I change the slider position, so I really don’t understand why the map is not updating…

Yes, in the callback.

Try first creating the figure outside the callback, and manually provide the different options and see if it works then put that function inside the callback.

Also print the figure variable before the return command.

Hi, thanks for that, but things work fine when the slider is not used: if I manually change the week number I get the correct maps.

If you can bild a DataFrame with few rows to use, I can try to see what’s going on.

Hi Eduardo,

Thanks again for your help! I just found the solution to the problem, I changed the animate=True to False in the dcc.graph part of the app.layout and it worked!

Here is my corrected code:

dcc.Graph(id='map', config={'displayModeBar': False}, animate=False)

Thanks again !

Ana

1 Like