Resetting click data when creating new choropleth map using filter

Hi, still fairly new to using plotly and dash. I’m making a choropleth graph that shows the ratio between two sets of data for England. The map works, the issue is that whenever I click on a local authority area and select it, then change the map using a dropdown the new choropleth map shows up not fully coloured in.

I believe this is probably to do with the ClickData being in a location that is no longer on the new choropleth map, so it just shows nothing or a random area.

For example:

I don’t click on an area (so presume no ClickData stored?) and choose london or any other region from the dropdown, all good:

But then if I click on an area and then, with it selected, choose another region from the dropdown (for example the South West) to create a new map, the new map loads like this:

I’ve tried creating a callback so that ClickData for the graph is None when the dropdown value changes, but that hasn’t seemed to have worked.

The code:

import dash
import pandas as pd
import plotly.express as px
from dash import Dash, dcc, html, Input, Output, State
import dash_bootstrap_components as dbc
import plotly.graph_objs as go
from dash_bootstrap_components.themes import UNITED
from dash_bootstrap_templates import load_figure_template
import numpy as np


#Load app and template
app = dash.Dash(external_stylesheets=[dbc.themes.UNITED])
load_figure_template("UNITED")

#Load data
df = pd.read_csv(r"LAlookup.csv")
earningdf = pd.read_csv(r"Medianincome.csv")
housedf = pd.read_csv(r"Medianhouseprice.csv")

#Set up options for year dropdown ---------------------------------------------
years_list = list(earningdf)
years_list.remove("LAD21NM")

for x in years_list:
    earningdf[x] = pd.to_numeric(earningdf[x], errors='coerce')

years_options_list = []

for y in years_list:
    years_dict = dict()
    years_dict["label"] = y
    years_dict["value"] = y
    years_options_list.append(years_dict)

# Set up options for region dropdown ---------------------------------------------------

regions = list(df.Region.unique())
regions = [item for item in regions if not (pd.isnull(item)) == True]
region_options_list = []

for region in regions:
    region_dict = dict()
    region_dict["label"] = str(region)
    region_dict["value"] = str(region)
    region_options_list.append(region_dict)


#To create dataframe used for graph -------------------------------------------------------------

def basicdataframe(region, year):
    newdf = df[df["Region"] == region]
    earningdfbyyear = earningdf [["LAD21NM", year]]
    housedfbyyear = housedf [["LAD21NM", str(year)]]

    df1 = pd.merge(
        left=newdf,
        right=earningdfbyyear,
        left_on='LAD21NM',
        right_on='LAD21NM',
        how='left')
    df2 = pd.merge(left=df1,
                   right=housedfbyyear,
                   left_on='LAD21NM',
                   right_on='LAD21NM',
                   how='left'
                   )

    earningcolname = (year + "_x")
    housecolname = (year + "_y")

    def ratio_row(row):
        x = row[housecolname]
        y = row[earningcolname]
        z = x/y
        return z

    df2['Ratio'] = df2.apply(lambda row: ratio_row(row), axis=1)
    df2.rename(columns = {"LAD21NM": "Local Authority"}, inplace = True)
    df2['pct_rank'] = (df2['Ratio'].rank(pct=True))*100
    df2['pct_rank'] = df2['pct_rank'].replace(np.nan, "")
    df2 = df2.round(1)

    return df2

#######---------------------- region filter Div ---------------------------------


region_filter = html.Div(
    [html.P(
        "selected region: ", className="lead"
    ),
        html.Div(dcc.Dropdown(id='region_picker', options=region_options_list, value="England", clearable=False), style={
            'width': '80%'
        }),
        html.Br(),
    ],
    style = {"padding": "0.5rem 0.5rem 0.5rem"}
)

#-------------------graph Div -----------------------------------

graph_bar = html.Div ([
    html.Div(dcc.Graph(id='graph',
                       style = {'width': '50vw', 'height': '70vh', "margin-left": "5px"}, config= {'displayModeBar': False}),
             style={'width': '100%', 'position':'relative'})
])

#------------------------- year filter Div ---------------------

year_filter = html.Div(
    [html.P(
        "selected year: ", className="lead"
    ),
        html.Div(dcc.Dropdown(id='year_picker', options=years_options_list, value="2021", clearable = False),
                 style={
                     'width': '60%', "float":"left"}),
        html.Br(),
    ],
    style = {"padding": "0.5rem 0.5rem 0.5rem" }
)


#-------------- app layout -----------------------------

app.layout = dbc.Container(children=[
    dbc.Row([
        dbc.Col(region_filter),
        dbc.Col(year_filter)
    ]),

    dbc.Row(
        [
            dbc.Col(graph_bar),
        ])
], fluid=True)

# Choropleth callback and figure creation

@app.callback(
    Output("graph", "figure"),
    Input("region_picker", "value"),
    Input("year_picker", "value"),
)

def display_choropleth(region, year):

    #Use data frame function to create dataframe for selected region and year
    choropleth_df = basicdataframe(region, year)

    # Set up json file
    with open(r"Local_Authority_Districts_(December_2021)_GB_BFC4.json") as json_file:
        geojson = json.load(json_file)

    # create figure
    fig = px.choropleth_mapbox(choropleth_df, geojson=geojson, color=choropleth_df["Ratio"],
                               locations=choropleth_df["Local Authority"], featureidkey="properties.LAD21NM",
                               color_continuous_scale= "YlOrRd",
                               hover_data= ["Local Authority"], opacity=0.7,
                               )
    fig.update_geos(fitbounds="locations", visible=False)
    fig.update_layout(autosize=False, margin={"r": 0, "t": 0, "l": 0, "b": 0, "autoexpand": True, "pad": 1}, width=900)

    #Centres to use in mapbox_center zoom
    centre_lat_long = {"England": {"lat": 52.567004, "lon": -1.180832},
                       "East of England": {"lat": 52.238061, "lon": 0.571506},
                       "West Midlands": {"lat": 52.523157, "lon": -2.189539},
                       "East Midlands": {"lat": 52.871699, "lon": -0.679063},
                       "South East": {"lat": 51.281418, "lon": -0.339193},
                       "South West": {"lat": 51.065737, "lon": -2.890518},
                       "North West": {"lat": 54.046005, "lon": -2.562678},
                       "North East": {"lat": 55.088114, "lon": -1.655882},
                       "London": {"lat": 51.507204, "lon": -0.119856},
                       "Yorkshire and The Humber": {"lat": 53.920193, "lon": -1.097800}
                       }

    #To get zoom right when different regions are selected
    non_london_zoom = 7
    zoom_for_mapbox =  {"England": 5.5,
                        "East of England": non_london_zoom,
                        "West Midlands": non_london_zoom,
                        "East Midlands":non_london_zoom ,
                        "South East": non_london_zoom,
                        "South West": 6.5,
                        "North West": non_london_zoom,
                        "North East": non_london_zoom,
                        "London": 9,
                        "Yorkshire and The Humber":non_london_zoom
                        }

    #Update layout of fig
    fig.update_layout(mapbox_style="carto-positron",
                      mapbox_zoom= zoom_for_mapbox[region],
                      mapbox_center={"lat": centre_lat_long[region]["lat"], "lon": centre_lat_long[region]["lon"]},
                      margin={"r":0,"t":0,"l":0,"b":0},
                      uirevision='constant')

    fig.update_layout(coloraxis_colorbar=dict(
        # title="Vacant homes to homeless ratio",
        yanchor="top", y=1,
        xanchor="left", x=1,
        dtick=5))

    fig.update_layout(clickmode='event+select')

    return fig


app.run_server(debug=True) ```


Any help is really appreciated