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?