"""Overview / dashboard home page.""" from __future__ import annotations import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parents[1])) import pandas as pd import streamlit as st from utils import data_loader as dl from utils.plotting import montana_with_hospitals from utils.styling import callout, page_setup, section, INITIATIVE_COLOR page_setup("Overview") # -------------------------------------------------------------------------- # Brand strip + headline # -------------------------------------------------------------------------- st.markdown( "
" "
" "
Montana DPHHS · Rural Health Transformation Program
" "

RHTP Evaluation Dashboard

" "
A fixed research plan, layered, causal evaluation of all five " "RHTP initiatives across Montana's 56 counties and 65 hospitals.
" "
", unsafe_allow_html=True, ) # -------------------------------------------------------------------------- # Top-line stats # -------------------------------------------------------------------------- counties = dl.counties() hosp = dl.hospitals() fq = dl.facility_quarter_ops() coe = dl.coe_implementation() wf = dl.workforce_panel() c1, c2, c3, c4, c5 = st.columns(5) with c1: st.metric("Hospitals tracked", f"{len(hosp):,}", help="Critical Access, PPS, Tertiary, Sole Community, and Tribal/IHS facilities.") with c2: rural = (counties["rurality"] != "Urban").sum() st.metric("Rural / tribal counties", f"{rural} / {len(counties)}") with c3: treated = (coe["coe_cohort"] != "never").sum() st.metric("CoE-enrolled facilities", f"{treated} / {len(hosp)}", delta=f"{treated/len(hosp):.0%}", delta_color="off") with c4: latest = fq.sort_values(["year", "quarter"]).groupby("facility_id").tail(1) neg_margin = (latest["operating_margin_pct"] < 0).sum() st.metric("Negative-margin hospitals (latest Q)", f"{neg_margin} / {len(latest)}", delta=f"{neg_margin/len(latest):.0%}", delta_color="off") with c5: pop = counties["population_2020"].sum() st.metric("Population covered", f"{pop:,.0f}") # -------------------------------------------------------------------------- # Evaluation framing # -------------------------------------------------------------------------- section("Evaluation framing", "How this dashboard is structured and what each page answers.") c1, c2 = st.columns([3, 2]) with c1: st.markdown( "Every initiative page follows the same three-section pattern:\n\n" "1. **Initiative scope** — KPOs (with baseline + FY2031 target + level) " "and treatment / intervention inputs, so you know exactly what each " "page is trying to move and which levers it pulls.\n" "2. **Data Explorer** — interactive panel of the underlying outcomes " "and treatments.\n" "3. **Models** — the exact econometric specification(s) for that " "initiative, with adjustable knobs so a stakeholder can see *how* an " "estimate is constructed.\n" "4. **Was the initiative successful?** — direction, magnitude, " "precision, timing, consistency, and dose-response, applied to the " "model's outputs.\n\n" "This structure mirrors the **RHTP_models_full** modeling playbook." ) callout( "About the data. Every file in /data/ is " "synthetic, generated by scripts/generate_data.py " "to mirror the schema and units of the real source feeds — CMS Hospital " "Cost Reports, Montana Medicaid claims, HRSA workforce data, BRFSS, " "Big Sky Care Connect HIE rosters, and the MT DPHHS facility / county " "files. Treatment effects are baked in deterministically (with realistic " "noise), so the models should recover positive effects on the " "outcomes the RHTP plan is designed to move. To switch the dashboard to " "live data, drop a real file with the same name and column schema into " "/data/ — no code changes needed.", kind="info", ) with c2: st.markdown("##### Five initiatives") initiatives = [ ("01", "Workforce"), ("02", "Facility Sustainability"), ("03", "Innovative Care & Payment"), ("04", "Community Prevention"), ("05", "Technology & Data"), ] for num, name in initiatives: color = INITIATIVE_COLOR[int(num)] st.markdown( f"
" f"
" f"INITIATIVE {num}" f"

{name}

" f"
" f"open via the sidebar
", unsafe_allow_html=True, ) # -------------------------------------------------------------------------- # Map # -------------------------------------------------------------------------- section("Montana hospitals by county", "Hover any county for population and rurality; hover any marker for the " "hospital name, facility type, staffed beds, ownership, and CCN.") ctrl_col, _ = st.columns([3, 1]) with ctrl_col: facility_types = sorted(hosp["facility_type"].unique().tolist()) selected_types = st.multiselect( "Facility types to display", options=facility_types, default=facility_types, help="Filter the map markers. The choropleth always shows all 56 counties.", ) if not selected_types: selected_types = facility_types fig = montana_with_hospitals(counties, hosp, facility_type_filter=selected_types, height=620) st.plotly_chart(fig, use_container_width=True, config={"displaylogo": False}) fcount = hosp[hosp["facility_type"].isin(selected_types)] beds_total = int(fcount["staffed_beds"].sum()) m1, m2, m3, m4 = st.columns(4) with m1: st.metric("Facilities shown", f"{len(fcount):,}") with m2: st.metric("Staffed beds", f"{beds_total:,}") with m3: cah = (fcount["facility_type"] == "CAH").sum() st.metric("Critical Access (CAH)", f"{cah:,}") with m4: tribal = (fcount["facility_type"] == "Tribal/IHS").sum() st.metric("Tribal / IHS", f"{tribal:,}") # -------------------------------------------------------------------------- # Hospital roster # -------------------------------------------------------------------------- section("Hospital roster", "Schema mirrors the CMS Provider of Services file plus the MT DPHHS " "facility roster — drop in real data with the same columns to switch " "from synthetic to live.") with st.expander("Show the full roster"): st.dataframe( hosp[[ "facility_id", "facility_name", "county_name", "facility_type", "ownership", "staffed_beds", "ccn", "rurality", "region", ]].sort_values(["facility_type", "facility_name"]), hide_index=True, use_container_width=True, ) # -------------------------------------------------------------------------- # Latest workforce snapshot # -------------------------------------------------------------------------- section("County baseline panel — workforce snapshot (latest year)", "Where Montana's rural workforce stood at the close of the most recent " "year of available data. Use this view alongside the Workforce page to " "judge what 'meaningfully improved' means relative to baseline.") latest_year = int(wf["year"].max()) wf_latest = wf[wf["year"] == latest_year].merge( counties[["fips", "county_name", "rurality", "region"]], on="fips") c1, c2 = st.columns(2) with c1: metric_choice = st.selectbox( "Metric to display", options=[ ("np_per_100k", "Nurse practitioners per 100k"), ("md_per_100k", "Physicians per 100k"), ("rn_per_100k", "Registered nurses per 100k"), ("turnover_rate", "Annual provider turnover rate"), ("provider_mh_score", "Provider mental health score (1-10)"), ], format_func=lambda x: x[1], ) metric_col, metric_label = metric_choice with c2: rurality_filter = st.multiselect( "Show counties by rurality", options=["Urban", "Rural", "Tribal"], default=["Urban", "Rural", "Tribal"], ) display_df = wf_latest[wf_latest["rurality"].isin(rurality_filter)].copy() display_df = display_df[["county_name", "rurality", "region", metric_col, "population", "medicaid_share", "unemployment_pct"]] display_df = display_df.rename(columns={ "county_name": "County", "rurality": "Type", "region": "Region", metric_col: metric_label, "population": "Population", "medicaid_share": "Medicaid share", "unemployment_pct": "Unemployment %", }) display_df = display_df.sort_values(metric_label, ascending=metric_col == "turnover_rate") st.dataframe(display_df, hide_index=True, use_container_width=True, height=320) # -------------------------------------------------------------------------- # Reading guide # -------------------------------------------------------------------------- section("How a stakeholder should read this evaluation") c1, c2, c3 = st.columns(3) with c1: st.markdown( "**Step 1 — Implementation.** Did the intervention actually roll out? " "Each initiative page begins by showing the cumulative reach of the " "intervention in question. Weak downstream effects are hard to " "interpret if the intervention barely reached anyone." ) with c2: st.markdown( "**Step 2 — Effect.** Did treated units improve more than comparable " "untreated ones? The models on each page are causal: they use county " "or facility fixed effects to absorb stable differences, year fixed " "effects to absorb statewide trends, and event-study structure to test " "*when* effects appear." ) with c3: st.markdown( "**Step 3 — Synthesis.** Across all five initiatives, did Montana move " "materially closer to its FY2031 rural health goals on workforce, " "access, quality, financial sustainability, and tech/data capacity? " "**That is the program-level success question — and it is a synthesis " "of many imperfect estimates, not a single p-value.**" ) st.markdown("
", unsafe_allow_html=True) callout( "Built as a working draft of the RHTP evaluation tool. Every visualization, model, " "and statistical test is fully reproducible from the file at " "/scripts/generate_data.py. Replace files in /data/ " "with real source data of the same schema to switch this dashboard from " "synthetic to live.", kind="info", title="About this dashboard", )