import streamlit as st
import geopandas
import pandas as pd
import folium
import random
from streamlit_folium import st_folium
import time
="wide")
st.set_page_config(layout
"Clinic Demand Estimator")
st.title(
= geopandas.read_file("lsoa_demand_demographics.geojson")
lsoa_demographics "Region"] = lsoa_demographics["LSOA21NM"].str.replace("( \d{3})\w", "", regex=True).str.strip()
lsoa_demographics[
= True
new_col
= lsoa_demographics.drop(
df_display = ["BNG_E", "BNG_N", "LONG", "LAT", "GlobalID", "geometry"]
columns
)
=2, column='Include', value=new_col)
df_display.insert(loc
= st.multiselect(
selected_regions "Select Regions to Include",
"Region"].drop_duplicates().sort_values().tolist(),
lsoa_demographics[=["Exeter"]
default
)
= st.data_editor(
edited_df "Region"].isin(selected_regions)]
df_display[df_display[
)
= pd.merge(
lsoa_demographics
lsoa_demographics,"Include"] == True][["LSOA21CD"]],
edited_df[edited_df[="inner"
how
)
= lsoa_demographics['Projected Average Daily Demand'].sum()*0.2
demand_calls = lsoa_demographics['Projected Average Daily Demand'].sum()*0.8
demand_walkins
= 480/(lsoa_demographics['Projected Average Daily Demand'].sum()*0.2)
iat_calls = 480/(lsoa_demographics['Projected Average Daily Demand'].sum()*0.8)
iat_walkins
f"Projected Daily Demand - Calls: {demand_calls:.1f}")
st.write(f"Average IAT: {iat_calls:.1f} minutes (assuming 480 minute day)")
st.write(
f"Projected Daily Demand - Walk-ins: {demand_walkins:.1f}")
st.write(f"Average IAT - Walk-ins: {iat_walkins:.1f} minutes (assuming 480 minute day)")
st.write(
#create base map
= folium.Map(
demand_demographic_map_interactive =[50.71671, -3.50668],
location=9,
zoom_start='cartodbpositron'
tiles
)
# create and add choropleth map
= folium.Choropleth(
choropleth =lsoa_demographics, # dataframe with geometry in it
geo_data=lsoa_demographics, # dataframe with data in - may be the same dataframe or a different one
data=['LSOA21CD', 'Projected Average Daily Demand'], # [key (field for geometry), field to plot]
columns='feature.properties.LSOA21CD',
key_on='OrRd',
fill_color=0.4,
fill_opacity=0.3,
line_weight='Projected Average Daily Demand',
legend_name=True, # highlight the LSOA shape when mouse pointer enters it
highlight=0
smooth_factor
)
= choropleth.add_to(demand_demographic_map_interactive)
choropleth
= choropleth.geojson.add_child(
choropleth
folium.features.GeoJsonTooltip('LSOA21CD', 'Projected Average Daily Demand'],
[=True
labels
)
)
st_folium(demand_demographic_map_interactive,=True)
use_container_width
st.divider()
"Complex Calculation Unrelated to the Map!")
st.subheader(
"Long-running calculation being calculated...")
st.write(
10)
time.sleep(
"Long-running calculation complete!")
st.write(
f"The answer is {random.randint(100, 500)}") st.write(
56 Exercise 6: DESpite Everything, It’s Still You
Let’s now make our app really powerful! We’re going to work with a new Streamlit app that works out the estimated demand for an area given its demographic features1, make it more efficient, and then incorporate it into our main app.
You will also need to make sure the following geojson is available: lsoa_demand_demographics.geojson
56.1 Tasks
The LSOA demographics file that new app loads in is really big!
- Switch to loading it in using the
@st.cache_data
decorator
- Switch to loading it in using the
There’s a long-running calculation in the second half of that page that isn’t anything to do with the map.
- Use the
@st.fragment
decorator so that changing the parameters of the map doesn’t trigger this calculation to rerun
- Use the
Add this new app as an extra page in your multipage DES app from the previous exercise
Use session state to save the caller and patient IAT figures from that new page
- then remove the ability for the user to specify the IAT for callers and patients
- replace the IAT used for the simulation with the IAT that you saved into the session state
56.1.1 Challenge Activity
Try saving some key outputs from each model run to the session state and use this to display a comparison of the outputs across these multiple runs
This is just a dummy app to show what’s possible - it’s not using a proper method to estimate the demand!↩︎