I am using Streamlit to create a Plotly Express choropleth map of counties in Georgia (USA) with shading based on the county population. I also have a slider widget above the map for the user to change the opacity of the map. Here is a full working example of the app, including URL for reading in the data:
import streamlit as st
import geopandas as gpd
import plotly.express as px
# set slider for map layer opacity
opacity = st.slider(
label='Set map layer opacity',
min_value=0.2,
max_value=1.0,
value=0.6,
step=0.1
)
# Define a function to fetch and cache the data
@st.cache_data
def fetch_data(url):
# clean the input URL
url = url.replace(" ", "%20")
# Read the GeoJSON data from the URL
gdf = gpd.read_file(url)
# Select the required columns for choropleth map
gdf = gdf[['GEOID', 'TotPop_e22', 'geometry']]
return gdf
# read in population, geometry of Georgia counties
url = "https://services1.arcgis.com/Ug5xGQbHsD8zuZzM/arcgis/rest/services/ACS 2022 Demographic Population GeoSplitJoined/FeatureServer/9/query?outFields=*&where=1%3D1&f=geojson"
gdf = fetch_data(url)
# create mapping figure
fig = px.choropleth_mapbox(
gdf,
geojson=gdf.geometry,
locations=gdf.index,
color='TotPop_e22',
center={"lat": 32.90, "lon": -83.50},
mapbox_style='carto-positron',
zoom=6,
opacity=opacity,
height=650
)
# plot the mapping figure
st.plotly_chart(
fig,
theme='streamlit',
use_container_width=True
)
The app works fine, but I can’t figure out why the entire application / map re-renders each time the slider changes. As the slider only impacts the visual style of the map, not the underlying data structure or fig
object, I am unsure how to keep this from happening.
Desired outcome: I would like the app to only load the data once, when the app initially opens, by using the st.cache_data decorator. Once the app is open, I would like to interact with the map by zooming, panning, etc. and then be able to change the opacity via the slider widget WITHOUT the entire application reloading & the map resetting each time the slider widget gets a new value for the opacity. Thank you for the help.