import%20marimo%0A%0A__generated_with%20%3D%20%220.23.9%22%0Aapp%20%3D%20marimo.App(width%3D%22medium%22)%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%20Elevation%20vs.%20realized%20flood%20claims%20%E2%80%94%20the%202024%20gradient%0A%0A%20%20%20%20**Question%3A**%20how%20much%20did%20*ground%20elevation*%20actually%20shape%20the%20insurance%20losses%0A%20%20%20%20from%20the%202024%20hurricanes%20(Helene%202024-09-26%20%2B%20Milton%202024-10-09)%3F%20Not%20modeled%20loss%20%E2%80%94%0A%20%20%20%20**realized%20NFIP%20claims**%2C%20read%20straight%20from%20what%20was%20paid.%0A%0A%20%20%20%20**Why%20it's%20a%20separate%20notebook.**%20The%20flood%20cat-model%20(%6008_catmodel_validation.py%60)%0A%20%20%20%20*predicts*%20loss%20from%20elevation%20%2B%20depth-damage%20physics%2C%20then%20checks%20itself%20against%20NFIP%0A%20%20%20%20claims%20(rung%20C).%20This%20notebook%20runs%20the%20check%20the%20other%20direction%20and%20**model-free**%3A%0A%20%20%20%20take%20realized%20claims%20as%20the%20dependent%20variable%20and%20ask%20whether%20elevation%20alone%20orders%0A%20%20%20%20them.%20If%20the%20raw%20data%20already%20shows%20the%20gradient%20the%20model%20assumes%2C%20that's%20independent%0A%20%20%20%20corroboration%20of%20the%20model's%20central%20mechanism%20%E2%80%94%20the%20two%20should%20agree%20without%20the%0A%20%20%20%20cat-model%20ever%20seeing%20a%20claim.%0A%0A%20%20%20%20**Plumbing.**%20Three%20real%20tables%2C%20no%20model%20in%20the%20loop%3A%0A%0A%20%20%20%20-%20%60flood_claims_bg%60%20%E2%80%94%20NFIP%20claims%20by%20**census%20block%20group%20%C3%97%20year**%20(OpenFEMA).%20The%0A%20%20%20%20%20%20finest%20grain%20the%20redacted%20federal%20data%20allows%3B%202024%20is%20Pinellas-wide.%0A%20%20%20%20-%20%60parcel_block_group%60%20%E2%80%94%20parcels%20spatially%20joined%20to%20TIGER%20block%20groups.%0A%20%20%20%20-%20%60nfip_policies%60%20%E2%80%94%20single-family%20policies-in-force%20per%20block%20group%20(take-up).%0A%20%20%20%20-%20**Elevation**%20is%20not%20a%20column%20anywhere%20%E2%80%94%20it%20is%20sampled%20per%20parcel%20from%20the%20USGS%203DEP%0A%20%20%20%20%20%20DEM%20(%60data%2Fdem%2F%60%2C%20NAVD88)%20with%20the%20*same*%20%60sample_ground_elevation_ft%60%20the%20cat-model's%0A%20%20%20%20%20%20exposure%20module%20uses%2C%20then%20aggregated%20to%20the%20block%20group.%0A%0A%20%20%20%20**Headline.**%20Elevation%20is%20the%20dominant%20gradient%20in%20realized%202024%20losses.%20A%20block%0A%20%20%20%20group's%20**low-lying%20tail**%20(10th-percentile%20parcel%20elevation)%20predicts%20claims%20better%0A%20%20%20%20than%20its%20mean%20%E2%80%94%20%CF%81%20%E2%89%88%20**%E2%88%920.77**%20vs%20claims-per-parcel%20%E2%80%94%20and%20the%20signal%20**survives%20take-up%0A%20%20%20%20normalization**%20(%CF%81%20%E2%89%88%20**%E2%88%920.53**%20for%20claims-per-*policy*).%20Below%205%20ft%3A%20~112%20claims%20per%0A%20%20%20%20100%20policies%20across%20the%20two%20storms%3B%20above%2015%20ft%3A%20~15.%20The%20model-free%20confirmation%20of%0A%20%20%20%20the%20cat-model's%20%22coast%20carries%20the%20tail%2C%20the%20dry%20ridge%20contributes%20%E2%89%88%20%5C%240.%22%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20import%20sys%0A%20%20%20%20from%20pathlib%20import%20Path%0A%0A%20%20%20%20import%20duckdb%0A%20%20%20%20import%20marimo%20as%20mo%0A%20%20%20%20import%20matplotlib.pyplot%20as%20plt%0A%20%20%20%20import%20numpy%20as%20np%0A%20%20%20%20import%20pandas%20as%20pd%0A%20%20%20%20from%20scipy.stats%20import%20spearmanr%0A%0A%20%20%20%20return%20Path%2C%20duckdb%2C%20mo%2C%20np%2C%20pd%2C%20plt%2C%20spearmanr%2C%20sys%0A%0A%0A%40app.cell%0Adef%20_(Path%2C%20duckdb%2C%20sys)%3A%0A%20%20%20%20def%20_find_root()%20-%3E%20Path%3A%0A%20%20%20%20%20%20%20%20for%20d%20in%20%5BPath.cwd()%2C%20*Path.cwd().parents%5D%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(d%20%2F%20%22analytics.db%22).exists()%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20d%0A%20%20%20%20%20%20%20%20raise%20FileNotFoundError(%22analytics.db%20not%20found%20walking%20up%20from%20cwd%22)%0A%0A%20%20%20%20_root%20%3D%20_find_root()%0A%20%20%20%20%23%20Reuse%20the%20cat-model's%20DEM%20sampler%20so%20elevation%20is%20defined%20identically%20here%20and%20there.%0A%20%20%20%20if%20str(_root)%20not%20in%20sys.path%3A%0A%20%20%20%20%20%20%20%20sys.path.insert(0%2C%20str(_root))%0A%20%20%20%20from%20analysis.catmodel.exposure%20import%20sample_ground_elevation_ft%0A%0A%20%20%20%20conn%20%3D%20duckdb.connect(str(_root%20%2F%20%22analytics.db%22)%2C%20read_only%3DTrue)%0A%20%20%20%20return%20conn%2C%20sample_ground_elevation_ft%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%23%20D1%20%E2%80%94%20universe%20%26%20grain%20(pre-data)%0A%0A%20%20%20%20Claims%20are%20only%20released%20at%20**block-group%20%C3%97%20year**%2C%20so%20the%20join%20lives%20at%20block%20group%3B%0A%20%20%20%20there%20is%20no%20parcel-level%20claim.%20Elevation%2C%20by%20contrast%2C%20is%20per%20parcel%2C%20so%20it%20is%0A%20%20%20%20aggregated%20up.%20Universe%20%3D%20every%20parcel%20mapped%20to%20a%20block%20group%20that%20recorded%20a%202024%0A%20%20%20%20NFIP%20claim%20(Pinellas-wide%20%E2%80%94%20the%202024%20claim%20footprint%2C%20not%20just%20St.%20Pete).%0A%0A%20%20%20%20%23%23%20D2%20%E2%80%94%20elevation%20is%20sampled%2C%20not%20assumed%20(pre-data)%0A%0A%20%20%20%20%60parcels.elevation_cert%60%20is%20a%20yes%2Fno%20flag%2C%20not%20a%20height.%20Ground%20elevation%20in%20feet%20comes%0A%20%20%20%20from%20the%20USGS%203DEP%20DEM%20at%20each%20parcel's%20lat%2Flon%20%E2%80%94%20the%20identical%20function%20the%20cat-model%0A%20%20%20%20exposure%20module%20uses%2C%20so%20%22elevation%22%20means%20the%20same%20thing%20in%20both%20notebooks.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(conn%2C%20sample_ground_elevation_ft)%3A%0A%20%20%20%20%23%20Every%20parcel%20in%20a%202024-claim%20block%20group%2C%20with%20coordinates%20-%3E%20sample%20DEM%20elevation.%0A%20%20%20%20_parcels%20%3D%20conn.execute(%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20%20%20%20%20SELECT%20pbg.block_group%2C%20p.parcel_id%2C%20p.latitude%2C%20p.longitude%0A%20%20%20%20%20%20%20%20FROM%20parcels%20p%0A%20%20%20%20%20%20%20%20JOIN%20parcel_block_group%20pbg%20USING%20(parcel_id)%0A%20%20%20%20%20%20%20%20WHERE%20p.latitude%20IS%20NOT%20NULL%20AND%20p.longitude%20IS%20NOT%20NULL%0A%20%20%20%20%20%20%20%20%20%20AND%20pbg.block_group%20IN%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20SELECT%20DISTINCT%20block_group%20FROM%20flood_claims_bg%20WHERE%20year%20%3D%202024%0A%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20).fetchdf()%0A%20%20%20%20_parcels%5B%22elev_ft%22%5D%20%3D%20sample_ground_elevation_ft(%0A%20%20%20%20%20%20%20%20_parcels%5B%22latitude%22%5D.to_numpy()%2C%20_parcels%5B%22longitude%22%5D.to_numpy()%0A%20%20%20%20)%0A%20%20%20%20parcels_elev%20%3D%20_parcels%0A%20%20%20%20dem_coverage%20%3D%20parcels_elev%5B%22elev_ft%22%5D.notna().mean()%0A%20%20%20%20parcels_elev%0A%20%20%20%20return%20dem_coverage%2C%20parcels_elev%0A%0A%0A%40app.cell%0Adef%20_(dem_coverage%2C%20mo%2C%20parcels_elev)%3A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20f%22%22%22%0A%20%20%20%20**Coverage%20note%20(read%20before%20trusting%20the%20aggregate).**%20The%20local%20DEM%20tile%0A%20%20%20%20(%60USGS_13_n28w083%60)%20spans%20lat%2027%E2%80%9328%C2%B0%2C%20so%20it%20covers%20St.%20Pete%20and%20mid-county%20but%20clips%0A%20%20%20%20the%20northern%20sliver%20of%20Pinellas%20above%20lat%2028%C2%B0%20(Palm%20Harbor%20%2F%20Tarpon%20Springs).%20DEM%0A%20%20%20%20coverage%20of%20parcels%20in%20claim%20block%20groups%20is%20**%7Bdem_coverage%3A.0%25%7D**%0A%20%20%20%20(%7B(~parcels_elev%5B%22elev_ft%22%5D.notna()).sum()%3A%2C%7D%20parcels%20fall%20off%20the%20tile%20and%20are%20dropped).%0A%20%20%20%20The%20surviving%20universe%20is%20effectively%20**south%20%2B%20central%20Pinellas**%20%E2%80%94%20which%20is%20exactly%0A%20%20%20%20where%20the%20elevation%20range%20is%20widest%20(coast%20%E2%89%88%200%E2%80%935%20ft%20vs%20the%2033713%20ridge%20%E2%89%88%2040%E2%80%9360%20ft)%20and%0A%20%20%20%20where%20the%20project's%20focus%20sits.%20The%20northern%20clip%20removes%20block%20groups%20wholesale%20rather%0A%20%20%20%20than%20biasing%20the%20ones%20that%20remain.%0A%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%23%20D3%20%E2%80%94%20aggregate%20elevation%2C%20and%20carry%20the%20low%20tail%20(pre-data)%0A%0A%20%20%20%20A%20block%20group%20is%20not%20flat.%20Flooding%20is%20driven%20by%20its%20*low*%20ground%2C%20not%20its%20average%2C%20so%0A%20%20%20%20alongside%20the%20mean%2Fmedian%20I%20keep%20the%20**10th-percentile%20elevation**%20(%60p10_elev%60)%20%E2%80%94%20a%0A%20%20%20%20robust%20stand-in%20for%20%22how%20low%20does%20this%20block%20group%20get.%22%20%60min_elev%60%20captures%20the%20same%0A%20%20%20%20idea%20but%20is%20a%20single%20noisy%20point%3B%20%60p10%60%20is%20the%20defensible%20version.%20Every%20rate%20below%0A%20%20%20%20carries%20its%20%60n%60%20(parcels%2C%20policies)%20so%20small%20block%20groups%20can't%20masquerade%20as%20signal.%0A%0A%20%20%20%20%23%23%20D4%20%E2%80%94%20normalize%20for%20take-up%20(pre-data)%0A%0A%20%20%20%20Raw%20%60total_paid%60%20confounds%20three%20things%3A%20how%20deep%20the%20water%20got%2C%20how%20many%20homes%20were%0A%20%20%20%20there%2C%20and%20how%20many%20of%20them%20carried%20flood%20insurance.%20To%20isolate%20the%20*flooding*%2C%20the%0A%20%20%20%20primary%20metric%20is%20**claims%20per%20policy-in-force**%20(%60claim_count%20%2F%20policy_count%60)%20%E2%80%94%20the%0A%20%20%20%20fraction%20of%20insured%20homes%20that%20actually%20filed%2C%20which%20nets%20out%20take-up%20the%20same%20way%20the%0A%20%20%20%20cat-model's%20rung%20C%20does.%20%60claims_per_parcel%60%20and%20%60total_paid%60%20are%20kept%20as%20exposure-%0A%20%20%20%20weighted%20companions%2C%20not%20the%20headline.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(conn%2C%20np%2C%20parcels_elev)%3A%0A%20%20%20%20%23%20Block-group%20elevation%20summary%20(drop%20off-tile%20parcels)%2C%20then%20join%20claims%20%2B%20policies.%0A%20%20%20%20_pe%20%3D%20parcels_elev.dropna(subset%3D%5B%22elev_ft%22%5D)%0A%20%20%20%20_bg%20%3D%20(%0A%20%20%20%20%20%20%20%20_pe.groupby(%22block_group%22)%0A%20%20%20%20%20%20%20%20.agg(%0A%20%20%20%20%20%20%20%20%20%20%20%20n_parcels%3D(%22parcel_id%22%2C%20%22size%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20mean_elev%3D(%22elev_ft%22%2C%20%22mean%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20median_elev%3D(%22elev_ft%22%2C%20%22median%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20min_elev%3D(%22elev_ft%22%2C%20%22min%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20p10_elev%3D(%22elev_ft%22%2C%20lambda%20s%3A%20s.quantile(0.10))%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20.reset_index()%0A%20%20%20%20)%0A%20%20%20%20_claims%20%3D%20conn.execute(%0A%20%20%20%20%20%20%20%20%22SELECT%20block_group%2C%20claim_count%2C%20total_paid%20FROM%20flood_claims_bg%20WHERE%20year%20%3D%202024%22%0A%20%20%20%20).fetchdf()%0A%20%20%20%20_pol%20%3D%20conn.execute(%0A%20%20%20%20%20%20%20%20%22SELECT%20geo_id%20AS%20block_group%2C%20policy_count%20FROM%20nfip_policies%22%0A%20%20%20%20).fetchdf()%0A%0A%20%20%20%20bg%20%3D%20_bg.merge(_claims%2C%20on%3D%22block_group%22%2C%20how%3D%22inner%22).merge(%0A%20%20%20%20%20%20%20%20_pol%2C%20on%3D%22block_group%22%2C%20how%3D%22left%22%0A%20%20%20%20)%0A%20%20%20%20bg%5B%22total_paid%22%5D%20%3D%20bg%5B%22total_paid%22%5D.astype(float)%0A%20%20%20%20bg%5B%22claims_per_policy%22%5D%20%3D%20bg%5B%22claim_count%22%5D%20%2F%20bg%5B%22policy_count%22%5D%0A%20%20%20%20bg%5B%22claims_per_parcel%22%5D%20%3D%20bg%5B%22claim_count%22%5D%20%2F%20bg%5B%22n_parcels%22%5D%0A%20%20%20%20bg%5B%22severity%22%5D%20%3D%20bg%5B%22total_paid%22%5D%20%2F%20bg%5B%22claim_count%22%5D.replace(0%2C%20np.nan)%0A%20%20%20%20bg%0A%20%20%20%20return%20(bg%2C)%0A%0A%0A%40app.cell%0Adef%20_(bg%2C%20mo)%3A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20f%22%22%22%0A%20%20%20%20**What%20landed%3A**%20**%7Blen(bg)%7D**%20block%20groups%20with%20both%20an%20elevation%20summary%20and%202024%0A%20%20%20%20claims%20(%7Bbg%5B%22policy_count%22%5D.notna().sum()%7D%20of%20them%20with%20policy%20counts%20for%20the%20take-up%0A%20%20%20%20normalization).%20Sanity%20check%20on%20the%20two-storm%20year%3A%20%7B(bg%5B%22claim_count%22%5D%20%3E%20bg%5B%22policy_count%22%5D).sum()%7D%0A%20%20%20%20block%20groups%20show%20*more*%20claims%20than%20policies-in-force%20%E2%80%94%20expected%2C%20since%20Helene%20and%0A%20%20%20%20Milton%20were%20separate%20events%20a%20policy%20could%20file%20against%20twice%20(and%20the%20policy%20snapshot%0A%20%20%20%20is%20current%2C%20not%20Sept-2024).%20This%20is%20why%20claims-per-policy%20can%20exceed%201.0%20in%20the%20hardest-%0A%20%20%20%20hit%2C%20thinly-insured%20coastal%20groups%3B%20carry%20%60n%60%20and%20read%20these%20loosely.%0A%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%23%23%20Elevation%20vs.%20claims%20%E2%80%94%20rank%20correlation%20(block-group%20level)%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(bg%2C%20pd%2C%20spearmanr)%3A%0A%20%20%20%20%23%20Continuous%20relationship%20first%3A%20Spearman%20rank%20corr%20(robust%20to%20the%20loose%2C%20skewed%20data).%0A%20%20%20%20_rows%20%3D%20%5B%5D%0A%20%20%20%20for%20_elev%20in%20%5B%22min_elev%22%2C%20%22p10_elev%22%2C%20%22median_elev%22%2C%20%22mean_elev%22%5D%3A%0A%20%20%20%20%20%20%20%20for%20_met%20in%20%5B%22claims_per_policy%22%2C%20%22claims_per_parcel%22%2C%20%22total_paid%22%2C%20%22severity%22%5D%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20_d%20%3D%20bg.dropna(subset%3D%5B_elev%2C%20_met%5D)%0A%20%20%20%20%20%20%20%20%20%20%20%20_rho%2C%20_p%20%3D%20spearmanr(_d%5B_elev%5D%2C%20_d%5B_met%5D)%0A%20%20%20%20%20%20%20%20%20%20%20%20_rows.append(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%22elevation_stat%22%3A%20_elev%2C%20%22claim_metric%22%3A%20_met%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22spearman_rho%22%3A%20round(_rho%2C%203)%2C%20%22p_value%22%3A%20_p%2C%20%22n%22%3A%20len(_d)%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20corr%20%3D%20pd.DataFrame(_rows)%0A%20%20%20%20corr%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20**Reading%20the%20table.**%20Every%20correlation%20is%20negative%20and%20most%20are%20large%20%E2%80%94%20higher%20ground%2C%0A%20%20%20%20fewer%2Fsmaller%20claims.%20Two%20things%20stand%20out%3A%0A%0A%20%20%20%20-%20**%60p10_elev%60%20beats%20%60mean_elev%60.**%20The%20low-lying%20tenth%20of%20a%20block%20group%20predicts%20its%0A%20%20%20%20%20%20claims%20(%CF%81%20%E2%89%88%20%E2%88%920.77%20vs%20claims-per-parcel)%20better%20than%20its%20average%20does.%20Flooding%20is%20a%0A%20%20%20%20%20%20*low-spot*%20phenomenon%3B%20block-group%20means%20blur%20the%20spots%20that%20actually%20take%20water%20%E2%80%94%0A%20%20%20%20%20%20which%20is%20the%20whole%20reason%20the%20cat-model%20works%20at%20parcel%20grain.%0A%20%20%20%20-%20**The%20signal%20survives%20take-up.**%20Even%20claims-per-*policy*%20(every%20home%20insured%2C%20so%0A%20%20%20%20%20%20take-up%20can't%20explain%20it)%20holds%20%CF%81%20%E2%89%88%20%E2%88%920.5.%20This%20is%20not%20%22low%20areas%20just%20buy%20more%20flood%0A%20%20%20%20%20%20insurance%22%20%E2%80%94%20conditional%20on%20holding%20a%20policy%2C%20low%20homes%20filed%20far%20more%20often.%0A%0A%20%20%20%20Severity%20(paid%20per%20claim)%20also%20falls%20with%20elevation%20(%CF%81%20%E2%89%88%20%E2%88%920.4)%3A%20low%20ground%20means%20deeper%0A%20%20%20%20water%20means%20bigger%20payouts.%20Elevation%20drives%20both%20*whether*%20you%20claimed%20and%20*how%20much*.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(bg%2C%20np%2C%20plt)%3A%0A%20%20%20%20%23%20The%20continuous%20picture%20behind%20the%20correlation%2C%20sized%20by%20policy%20count%20(the%20n).%0A%20%20%20%20_d%20%3D%20bg.dropna(subset%3D%5B%22p10_elev%22%2C%20%22claims_per_policy%22%2C%20%22policy_count%22%5D)%0A%20%20%20%20_fig%2C%20_ax%20%3D%20plt.subplots(figsize%3D(8%2C%205))%0A%20%20%20%20_ax.scatter(%0A%20%20%20%20%20%20%20%20_d%5B%22p10_elev%22%5D%2C%20_d%5B%22claims_per_policy%22%5D%2C%0A%20%20%20%20%20%20%20%20s%3Dnp.clip(_d%5B%22policy_count%22%5D%20%2F%206%2C%208%2C%20240)%2C%0A%20%20%20%20%20%20%20%20alpha%3D0.45%2C%20color%3D%22%234C72B0%22%2C%20edgecolor%3D%22white%22%2C%20linewidth%3D0.5%2C%0A%20%20%20%20)%0A%20%20%20%20_ax.set_yscale(%22log%22)%0A%20%20%20%20_ax.axhline(1.0%2C%20color%3D%22gray%22%2C%20lw%3D0.8%2C%20ls%3D%22--%22)%0A%20%20%20%20_ax.text(_d%5B%22p10_elev%22%5D.max()%2C%201.05%2C%20%221%20claim%20%2F%20policy%22%2C%20ha%3D%22right%22%2C%20va%3D%22bottom%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20fontsize%3D8%2C%20color%3D%22gray%22)%0A%20%20%20%20_ax.set_xlabel(%22block-group%20low-tail%20elevation%20%20(p10%20of%20parcel%20ground%20elev%2C%20ft%20NAVD88)%22)%0A%20%20%20%20_ax.set_ylabel(%22claims%20per%20policy-in-force%20%20(2024%2C%20log%20scale)%22)%0A%20%20%20%20_ax.set_title(%22Lower%20ground%2C%20far%20more%20claims%20%E2%80%94%20and%20take-up%20doesn't%20explain%20it%5Cn%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22(bubble%20size%20%3D%20policies-in-force)%22)%0A%20%20%20%20_ax.grid(alpha%3D0.3)%0A%20%20%20%20_fig%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(bg%2C%20pd)%3A%0A%20%20%20%20%23%20Post-hoc%20bands%20for%20readability%20ONLY%20%E2%80%94%20the%20analysis%20above%20is%20on%20the%20continuous%20variable.%0A%20%20%20%20_b%20%3D%20bg.copy()%0A%20%20%20%20_b%5B%22elev_band%22%5D%20%3D%20pd.cut(%0A%20%20%20%20%20%20%20%20_b%5B%22median_elev%22%5D%2C%20%5B-5%2C%205%2C%2010%2C%2015%2C%2025%2C%20100%5D%2C%0A%20%20%20%20%20%20%20%20labels%3D%5B%22%3C5%20ft%22%2C%20%225-10%20ft%22%2C%20%2210-15%20ft%22%2C%20%2215-25%20ft%22%2C%20%22%3E25%20ft%22%5D%2C%0A%20%20%20%20)%0A%20%20%20%20band%20%3D%20(%0A%20%20%20%20%20%20%20%20_b.groupby(%22elev_band%22%2C%20observed%3DTrue)%0A%20%20%20%20%20%20%20%20.agg(%0A%20%20%20%20%20%20%20%20%20%20%20%20n_bg%3D(%22block_group%22%2C%20%22size%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20parcels%3D(%22n_parcels%22%2C%20%22sum%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20policies%3D(%22policy_count%22%2C%20%22sum%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20claims%3D(%22claim_count%22%2C%20%22sum%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20paid_M%3D(%22total_paid%22%2C%20lambda%20s%3A%20round(s.sum()%20%2F%201e6%2C%201))%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20.reset_index()%0A%20%20%20%20)%0A%20%20%20%20band%5B%22claims_per_100_policies%22%5D%20%3D%20(band%5B%22claims%22%5D%20%2F%20band%5B%22policies%22%5D%20*%20100).round(1)%0A%20%20%20%20band%5B%22paid_per_policy_k%22%5D%20%3D%20(band%5B%22paid_M%22%5D%20*%201e6%20%2F%20band%5B%22policies%22%5D%20%2F%201e3).round(1)%0A%20%20%20%20band%0A%20%20%20%20return%20(band%2C)%0A%0A%0A%40app.cell%0Adef%20_(band%2C%20plt)%3A%0A%20%20%20%20_fig%2C%20_ax%20%3D%20plt.subplots(figsize%3D(8%2C%204.5))%0A%20%20%20%20_bars%20%3D%20_ax.bar(band%5B%22elev_band%22%5D.astype(str)%2C%20band%5B%22claims_per_100_policies%22%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20color%3D%22%234C72B0%22%2C%20edgecolor%3D%22black%22%2C%20linewidth%3D0.5)%0A%20%20%20%20_ax.bar_label(_bars%2C%20fmt%3D%22%25.0f%22%2C%20padding%3D2%2C%20fontsize%3D9)%0A%20%20%20%20_ax.set_xlabel(%22block-group%20median%20ground%20elevation%20(post-hoc%20band)%22)%0A%20%20%20%20_ax.set_ylabel(%22claims%20per%20100%20policies-in-force%20(2024)%22)%0A%20%20%20%20_ax.set_title(%22The%20take-up-normalized%20flood%20gradient%3A%20~7x%20from%20coast%20to%20high%20ground%22)%0A%20%20%20%20_ax.grid(alpha%3D0.3%2C%20axis%3D%22y%22)%0A%20%20%20%20_fig%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%23%20Findings%0A%0A%20%20%20%20%7C%20ID%20%7C%20Observation%20%7C%20Quality%20%7C%20Implication%20%7C%0A%20%20%20%20%7C----%7C-------------%7C---------%7C-------------%7C%0A%20%20%20%20%7C%20F1%20%7C%20DEM%20covers%2075%25%20of%20claim-BG%20parcels%3B%20the%2025%25%20lost%20is%20the%20north-county%20clip%20above%20lat%2028%C2%B0%2C%20removing%20block%20groups%20wholesale%2C%20not%20biasing%20survivors%20%7C%20caveat%20%7C%20Universe%20%3D%20south%2Fcentral%20Pinellas%20%E2%80%94%20widest%20elevation%20range%2C%20project%20focus%3B%20state%20the%20clip%2C%20don't%20hide%20it%20%7C%0A%20%20%20%20%7C%20F2%20%7C%20Elevation%E2%86%94claims%20is%20strongly%20negative%20and%20monotonic%20across%20all%20four%20elevation%20stats%20and%20all%20claim%20metrics%20(%CF%81%20%E2%88%920.40%20%E2%80%A6%20%E2%88%920.77)%20%7C%20clean%20%7C%20Elevation%20is%20*the*%20first-order%20gradient%20in%20realized%202024%20losses%20%7C%0A%20%20%20%20%7C%20F3%20%7C%20%60p10_elev%60%20(low%20tail)%20out-predicts%20%60mean_elev%60%20for%20every%20claim%20metric%20%7C%20clean%20%7C%20Flooding%20is%20a%20low-spot%20phenomenon%3B%20BG%20means%20blur%20it%20%E2%86%92%20motivates%20parcel-grain%20modeling%20(the%20cat-model)%20%7C%0A%20%20%20%20%7C%20F4%20%7C%20Take-up-normalized%20claims-per-policy%20still%20%CF%81%20%E2%89%88%20%E2%88%920.53%20with%20elevation%20%7C%20signal%20%7C%20Not%20a%20take-up%20artifact%20%E2%80%94%20conditional%20on%20a%20policy%2C%20low%20homes%20filed%20~7%C3%97%20more%20(112%20vs%20~15%20per%20100%20policies)%20%7C%0A%20%20%20%20%7C%20F5%20%7C%20Severity%20(paid%2Fclaim)%20falls%20with%20elevation%20(%CF%81%20%E2%89%88%20%E2%88%920.42)%20%7C%20signal%20%7C%20Low%20ground%20%E2%86%92%20deeper%20water%20%E2%86%92%20bigger%20payouts%3B%20elevation%20drives%20frequency%20*and*%20severity%20%7C%0A%20%20%20%20%7C%20F6%20%7C%20Gradient%20flattens%20above%20~15%20ft%3B%20the%20small%20residual%20at%20%3E25%20ft%20is%20non-monotonic%20noise%20(488%20claims%2C%20mix%20of%20rain%2Fpluvial%2C%20not%20surge)%20%7C%20caveat%20%7C%20The%20empirical%20form%20of%20%22the%20ridge%20is%20dry-resilient%22%20%E2%80%94%20surge%20can't%20reach%20it%3B%20residual%20claims%20aren't%20surge%20%7C%0A%0A%20%20%20%20%23%23%20Verdict%0A%0A%20%20%20%20Read%20straight%20off%20the%20checks%20the%20federal%20government%20cut%2C%20with%20no%20model%20in%20the%20loop%3A%0A%20%20%20%20**the%202024%20hurricane%20insurance%20losses%20were%2C%20first%20and%20foremost%2C%20an%20elevation%20story.**%0A%20%20%20%20A%20block%20group's%20low-lying%20ground%20predicts%20its%20NFIP%20claims%20more%20sharply%20than%20its%20average%0A%20%20%20%20ground%20does%2C%20and%20the%20gradient%20holds%20even%20after%20netting%20out%20who%20bought%20insurance%20%E2%80%94%20a%20~7%C3%97%0A%20%20%20%20swing%20in%20claim%20frequency%20and%20a%20~10%C3%97%20swing%20in%20dollars-paid-per-policy%20from%20the%20coast%20up%0A%20%20%20%20to%20high%20ground%2C%20fading%20to%20rain-driven%20noise%20above%20~15%20ft.%0A%0A%20%20%20%20This%20is%20the%20**model-independent%20twin**%20of%20the%20cat-model's%20central%20result.%20The%20cat-model%0A%20%20%20%20derives%20%22coast%20carries%20the%20tail%2C%20the%2033713%20ridge%20contributes%20%E2%89%88%20%5C%240%22%20from%20elevation%20%2B%0A%20%20%20%20depth-damage%20physics%3B%20here%20the%20realized%20claims%20say%20the%20same%20thing%20without%20the%20model%20ever%0A%20%20%20%20being%20consulted.%20Two%20roads%2C%20same%20destination%20%E2%80%94%20which%20is%20exactly%20the%20corroboration%20a%0A%20%20%20%20portfolio%20reviewer%20should%20want%20before%20trusting%20either%20one.%20For%20the%20buy%20decision%20the%20read%0A%20%20%20%20is%20unchanged%20and%20now%20doubly%20grounded%3A%20**dry%2C%20high%20ground%20is%20the%20structural%20hedge.**%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
984c7c85005617a21a3120674db6b67e