|
44 | 44 | "id": "imports", |
45 | 45 | "metadata": { |
46 | 46 | "execution": { |
47 | | - "iopub.execute_input": "2026-03-12T15:58:16.201132Z", |
48 | | - "iopub.status.busy": "2026-03-12T15:58:16.201023Z", |
49 | | - "iopub.status.idle": "2026-03-12T15:58:17.345528Z", |
50 | | - "shell.execute_reply": "2026-03-12T15:58:17.344603Z" |
| 47 | + "iopub.execute_input": "2026-03-13T02:48:12.809031Z", |
| 48 | + "iopub.status.busy": "2026-03-13T02:48:12.808873Z", |
| 49 | + "iopub.status.idle": "2026-03-13T02:48:15.149242Z", |
| 50 | + "shell.execute_reply": "2026-03-13T02:48:15.148679Z" |
51 | 51 | } |
52 | 52 | }, |
53 | 53 | "outputs": [], |
|
80 | 80 | "id": "load-dem", |
81 | 81 | "metadata": { |
82 | 82 | "execution": { |
83 | | - "iopub.execute_input": "2026-03-12T15:58:17.347258Z", |
84 | | - "iopub.status.busy": "2026-03-12T15:58:17.346967Z", |
85 | | - "iopub.status.idle": "2026-03-12T15:58:18.575181Z", |
86 | | - "shell.execute_reply": "2026-03-12T15:58:18.574616Z" |
| 83 | + "iopub.execute_input": "2026-03-13T02:48:15.150597Z", |
| 84 | + "iopub.status.busy": "2026-03-13T02:48:15.150328Z", |
| 85 | + "iopub.status.idle": "2026-03-13T02:48:17.828701Z", |
| 86 | + "shell.execute_reply": "2026-03-13T02:48:17.828047Z" |
87 | 87 | } |
88 | 88 | }, |
89 | 89 | "outputs": [], |
|
128 | 128 | "id": "hydro-setup", |
129 | 129 | "metadata": { |
130 | 130 | "execution": { |
131 | | - "iopub.execute_input": "2026-03-12T15:58:18.576434Z", |
132 | | - "iopub.status.busy": "2026-03-12T15:58:18.576174Z", |
133 | | - "iopub.status.idle": "2026-03-12T15:58:19.593667Z", |
134 | | - "shell.execute_reply": "2026-03-12T15:58:19.592846Z" |
| 131 | + "iopub.execute_input": "2026-03-13T02:48:17.829970Z", |
| 132 | + "iopub.status.busy": "2026-03-13T02:48:17.829696Z", |
| 133 | + "iopub.status.idle": "2026-03-13T02:48:18.999397Z", |
| 134 | + "shell.execute_reply": "2026-03-13T02:48:18.998831Z" |
135 | 135 | } |
136 | 136 | }, |
137 | 137 | "outputs": [], |
|
159 | 159 | "id": "basemap", |
160 | 160 | "metadata": { |
161 | 161 | "execution": { |
162 | | - "iopub.execute_input": "2026-03-12T15:58:19.595270Z", |
163 | | - "iopub.status.busy": "2026-03-12T15:58:19.595161Z", |
164 | | - "iopub.status.idle": "2026-03-12T15:58:20.065838Z", |
165 | | - "shell.execute_reply": "2026-03-12T15:58:20.065162Z" |
| 162 | + "iopub.execute_input": "2026-03-13T02:48:19.000845Z", |
| 163 | + "iopub.status.busy": "2026-03-13T02:48:19.000727Z", |
| 164 | + "iopub.status.idle": "2026-03-13T02:48:19.338846Z", |
| 165 | + "shell.execute_reply": "2026-03-13T02:48:19.338124Z" |
166 | 166 | } |
167 | 167 | }, |
168 | 168 | "outputs": [], |
169 | 169 | "source": [ |
170 | 170 | "# Build a hillshade basemap we'll reuse throughout\n", |
171 | 171 | "hillshade = xrspatial.hillshade(dem)\n", |
172 | 172 | "\n", |
173 | | - "stream_cmap = LinearSegmentedColormap.from_list('water', ['lightblue', 'darkblue'])\n", |
| 173 | + "stream_cmap = LinearSegmentedColormap.from_list('water', ['#6baed6', '#08306b'])\n", |
174 | 174 | "\n", |
175 | 175 | "# Extract the stream network for context\n", |
176 | 176 | "threshold = 200\n", |
|
182 | 182 | "\n", |
183 | 183 | "fig, ax = plt.subplots(figsize=(10, 7.5))\n", |
184 | 184 | "hillshade.plot.imshow(ax=ax, cmap='gray', add_colorbar=False)\n", |
185 | | - "dem.plot.imshow(ax=ax, cmap='terrain', alpha=0.5, add_colorbar=False)\n", |
186 | | - "streams.plot.imshow(ax=ax, cmap=stream_cmap, alpha=220/255, add_colorbar=False,\n", |
| 185 | + "streams.plot.imshow(ax=ax, cmap=stream_cmap, alpha=0.9, add_colorbar=False,\n", |
187 | 186 | " norm=LogNorm(vmin=stream_vmin))\n", |
188 | | - "ax.legend(handles=[Patch(facecolor='steelblue', alpha=0.86, label='Stream network')],\n", |
| 187 | + "ax.legend(handles=[Patch(facecolor='#2171b5', label='Stream network')],\n", |
189 | 188 | " loc='lower right', fontsize=11, framealpha=0.9)\n", |
190 | 189 | "ax.set_axis_off()\n", |
191 | 190 | "plt.tight_layout()" |
|
217 | 216 | "id": "hand", |
218 | 217 | "metadata": { |
219 | 218 | "execution": { |
220 | | - "iopub.execute_input": "2026-03-12T15:58:20.068367Z", |
221 | | - "iopub.status.busy": "2026-03-12T15:58:20.068262Z", |
222 | | - "iopub.status.idle": "2026-03-12T15:58:20.603342Z", |
223 | | - "shell.execute_reply": "2026-03-12T15:58:20.602558Z" |
| 219 | + "iopub.execute_input": "2026-03-13T02:48:19.340736Z", |
| 220 | + "iopub.status.busy": "2026-03-13T02:48:19.340620Z", |
| 221 | + "iopub.status.idle": "2026-03-13T02:48:19.901710Z", |
| 222 | + "shell.execute_reply": "2026-03-13T02:48:19.901260Z" |
224 | 223 | } |
225 | 224 | }, |
226 | 225 | "outputs": [], |
|
230 | 229 | "print(f\"HAND range: {np.nanmin(hand_raster.values):.1f} to \"\n", |
231 | 230 | " f\"{np.nanmax(hand_raster.values):.1f} m\")\n", |
232 | 231 | "\n", |
233 | | - "hand_cmap = LinearSegmentedColormap.from_list('hand', ['darkblue', 'cyan', 'yellow', 'red'])\n", |
| 232 | + "hand_cmap = LinearSegmentedColormap.from_list('hand', ['#08306b', '#2171b5', '#fee08b', '#d73027'])\n", |
234 | 233 | "\n", |
235 | 234 | "fig, ax = plt.subplots(figsize=(10, 7.5))\n", |
236 | 235 | "hillshade.plot.imshow(ax=ax, cmap='gray', add_colorbar=False)\n", |
237 | | - "hand_raster.plot.imshow(ax=ax, cmap=hand_cmap, alpha=160/255, add_colorbar=True,\n", |
| 236 | + "hand_raster.plot.imshow(ax=ax, cmap=hand_cmap, alpha=0.75, add_colorbar=True,\n", |
238 | 237 | " cbar_kwargs={'label': 'HAND (m)', 'shrink': 0.7})\n", |
239 | 238 | "ax.set_axis_off()\n", |
240 | 239 | "plt.tight_layout()" |
|
268 | 267 | "id": "inundation", |
269 | 268 | "metadata": { |
270 | 269 | "execution": { |
271 | | - "iopub.execute_input": "2026-03-12T15:58:20.605224Z", |
272 | | - "iopub.status.busy": "2026-03-12T15:58:20.605116Z", |
273 | | - "iopub.status.idle": "2026-03-12T15:58:20.614417Z", |
274 | | - "shell.execute_reply": "2026-03-12T15:58:20.613315Z" |
| 270 | + "iopub.execute_input": "2026-03-13T02:48:19.904535Z", |
| 271 | + "iopub.status.busy": "2026-03-13T02:48:19.904425Z", |
| 272 | + "iopub.status.idle": "2026-03-13T02:48:19.912541Z", |
| 273 | + "shell.execute_reply": "2026-03-13T02:48:19.912025Z" |
275 | 274 | } |
276 | 275 | }, |
277 | 276 | "outputs": [], |
|
289 | 288 | "id": "inundation-viz", |
290 | 289 | "metadata": { |
291 | 290 | "execution": { |
292 | | - "iopub.execute_input": "2026-03-12T15:58:20.615814Z", |
293 | | - "iopub.status.busy": "2026-03-12T15:58:20.615698Z", |
294 | | - "iopub.status.idle": "2026-03-12T15:58:21.035448Z", |
295 | | - "shell.execute_reply": "2026-03-12T15:58:21.034852Z" |
| 291 | + "iopub.execute_input": "2026-03-13T02:48:19.913599Z", |
| 292 | + "iopub.status.busy": "2026-03-13T02:48:19.913498Z", |
| 293 | + "iopub.status.idle": "2026-03-13T02:48:20.201718Z", |
| 294 | + "shell.execute_reply": "2026-03-13T02:48:20.200986Z" |
296 | 295 | } |
297 | 296 | }, |
298 | 297 | "outputs": [], |
|
306 | 305 | "\n", |
307 | 306 | "fig, ax = plt.subplots(figsize=(10, 7.5))\n", |
308 | 307 | "hillshade.plot.imshow(ax=ax, cmap='gray', add_colorbar=False)\n", |
309 | | - "dem.plot.imshow(ax=ax, cmap='terrain', alpha=0.5, add_colorbar=False)\n", |
310 | 308 | "flood_viz.plot.imshow(ax=ax, cmap=ListedColormap(['steelblue']),\n", |
311 | | - " alpha=200/255, add_colorbar=False)\n", |
312 | | - "ax.legend(handles=[Patch(facecolor='steelblue', alpha=0.78, label='Flooded (10 m)')],\n", |
| 309 | + " alpha=0.8, add_colorbar=False)\n", |
| 310 | + "ax.legend(handles=[Patch(facecolor='steelblue', alpha=0.8, label='Flooded (10 m)')],\n", |
313 | 311 | " loc='lower right', fontsize=11, framealpha=0.9)\n", |
314 | 312 | "ax.set_axis_off()\n", |
315 | 313 | "plt.tight_layout()" |
|
343 | 341 | "id": "depth", |
344 | 342 | "metadata": { |
345 | 343 | "execution": { |
346 | | - "iopub.execute_input": "2026-03-12T15:58:21.036983Z", |
347 | | - "iopub.status.busy": "2026-03-12T15:58:21.036879Z", |
348 | | - "iopub.status.idle": "2026-03-12T15:58:21.425147Z", |
349 | | - "shell.execute_reply": "2026-03-12T15:58:21.424340Z" |
| 344 | + "iopub.execute_input": "2026-03-13T02:48:20.203145Z", |
| 345 | + "iopub.status.busy": "2026-03-13T02:48:20.203019Z", |
| 346 | + "iopub.status.idle": "2026-03-13T02:48:20.469517Z", |
| 347 | + "shell.execute_reply": "2026-03-13T02:48:20.468837Z" |
350 | 348 | } |
351 | 349 | }, |
352 | 350 | "outputs": [], |
|
360 | 358 | "print(f\" median: {np.median(flooded_vals):.2f} m\")\n", |
361 | 359 | "print(f\" max: {flooded_vals.max():.2f} m\")\n", |
362 | 360 | "\n", |
363 | | - "heat_cmap = LinearSegmentedColormap.from_list('heat', ['lightyellow', 'orange', 'darkred'])\n", |
| 361 | + "depth_cmap = LinearSegmentedColormap.from_list('depth', ['#ffffcc', '#fd8d3c', '#800026'])\n", |
364 | 362 | "\n", |
365 | 363 | "fig, ax = plt.subplots(figsize=(10, 7.5))\n", |
366 | 364 | "hillshade.plot.imshow(ax=ax, cmap='gray', add_colorbar=False)\n", |
367 | | - "dem.plot.imshow(ax=ax, cmap='terrain', alpha=0.5, add_colorbar=False)\n", |
368 | | - "depth.plot.imshow(ax=ax, cmap=heat_cmap, alpha=200/255, add_colorbar=True,\n", |
| 365 | + "depth.plot.imshow(ax=ax, cmap=depth_cmap, alpha=0.85, add_colorbar=True,\n", |
369 | 366 | " cbar_kwargs={'label': 'Flood depth (m)', 'shrink': 0.7})\n", |
370 | 367 | "ax.set_axis_off()\n", |
371 | 368 | "plt.tight_layout()" |
|
389 | 386 | "id": "cn-scalar", |
390 | 387 | "metadata": { |
391 | 388 | "execution": { |
392 | | - "iopub.execute_input": "2026-03-12T15:58:21.428035Z", |
393 | | - "iopub.status.busy": "2026-03-12T15:58:21.427929Z", |
394 | | - "iopub.status.idle": "2026-03-12T15:58:21.436698Z", |
395 | | - "shell.execute_reply": "2026-03-12T15:58:21.435921Z" |
| 389 | + "iopub.execute_input": "2026-03-13T02:48:20.470974Z", |
| 390 | + "iopub.status.busy": "2026-03-13T02:48:20.470859Z", |
| 391 | + "iopub.status.idle": "2026-03-13T02:48:20.478920Z", |
| 392 | + "shell.execute_reply": "2026-03-13T02:48:20.478270Z" |
396 | 393 | } |
397 | 394 | }, |
398 | 395 | "outputs": [], |
|
424 | 421 | "id": "cn-spatial", |
425 | 422 | "metadata": { |
426 | 423 | "execution": { |
427 | | - "iopub.execute_input": "2026-03-12T15:58:21.437987Z", |
428 | | - "iopub.status.busy": "2026-03-12T15:58:21.437879Z", |
429 | | - "iopub.status.idle": "2026-03-12T15:58:21.720498Z", |
430 | | - "shell.execute_reply": "2026-03-12T15:58:21.720008Z" |
| 424 | + "iopub.execute_input": "2026-03-13T02:48:20.480047Z", |
| 425 | + "iopub.status.busy": "2026-03-13T02:48:20.479949Z", |
| 426 | + "iopub.status.idle": "2026-03-13T02:48:20.764827Z", |
| 427 | + "shell.execute_reply": "2026-03-13T02:48:20.764276Z" |
431 | 428 | } |
432 | 429 | }, |
433 | 430 | "outputs": [], |
|
444 | 441 | "print(f\" valley (CN=85): {runoff.values[cn_raster.values == 85].mean():.1f} mm\")\n", |
445 | 442 | "print(f\" hills (CN=55): {runoff.values[cn_raster.values == 55].mean():.1f} mm\")\n", |
446 | 443 | "\n", |
447 | | - "heat_cmap = LinearSegmentedColormap.from_list('heat', ['lightyellow', 'orange', 'darkred'])\n", |
| 444 | + "runoff_cmap = LinearSegmentedColormap.from_list('runoff', ['#ffffcc', '#fd8d3c', '#800026'])\n", |
448 | 445 | "\n", |
449 | 446 | "fig, ax = plt.subplots(figsize=(10, 7.5))\n", |
450 | 447 | "hillshade.plot.imshow(ax=ax, cmap='gray', add_colorbar=False)\n", |
451 | | - "runoff.plot.imshow(ax=ax, cmap=heat_cmap, alpha=200/255, add_colorbar=True,\n", |
| 448 | + "runoff.plot.imshow(ax=ax, cmap=runoff_cmap, alpha=0.8, add_colorbar=True,\n", |
452 | 449 | " cbar_kwargs={'label': 'Runoff (mm)', 'shrink': 0.7})\n", |
453 | 450 | "ax.set_axis_off()\n", |
454 | 451 | "plt.tight_layout()" |
|
482 | 479 | "id": "tt-inputs", |
483 | 480 | "metadata": { |
484 | 481 | "execution": { |
485 | | - "iopub.execute_input": "2026-03-12T15:58:21.721815Z", |
486 | | - "iopub.status.busy": "2026-03-12T15:58:21.721702Z", |
487 | | - "iopub.status.idle": "2026-03-12T15:58:22.111770Z", |
488 | | - "shell.execute_reply": "2026-03-12T15:58:22.110884Z" |
| 482 | + "iopub.execute_input": "2026-03-13T02:48:20.766341Z", |
| 483 | + "iopub.status.busy": "2026-03-13T02:48:20.766235Z", |
| 484 | + "iopub.status.idle": "2026-03-13T02:48:21.170917Z", |
| 485 | + "shell.execute_reply": "2026-03-13T02:48:21.170083Z" |
489 | 486 | } |
490 | 487 | }, |
491 | 488 | "outputs": [], |
|
505 | 502 | "id": "tt-compute", |
506 | 503 | "metadata": { |
507 | 504 | "execution": { |
508 | | - "iopub.execute_input": "2026-03-12T15:58:22.113145Z", |
509 | | - "iopub.status.busy": "2026-03-12T15:58:22.113043Z", |
510 | | - "iopub.status.idle": "2026-03-12T15:58:22.419928Z", |
511 | | - "shell.execute_reply": "2026-03-12T15:58:22.419212Z" |
| 505 | + "iopub.execute_input": "2026-03-13T02:48:21.172210Z", |
| 506 | + "iopub.status.busy": "2026-03-13T02:48:21.172107Z", |
| 507 | + "iopub.status.idle": "2026-03-13T02:48:21.478814Z", |
| 508 | + "shell.execute_reply": "2026-03-13T02:48:21.478274Z" |
512 | 509 | } |
513 | 510 | }, |
514 | 511 | "outputs": [], |
|
521 | 518 | "print(f\"Travel time range: {tt_vals.min():.1f} to {tc:.1f}\")\n", |
522 | 519 | "print(f\"Time of concentration (max travel time): {tc:.1f}\")\n", |
523 | 520 | "\n", |
524 | | - "tt_cmap = LinearSegmentedColormap.from_list('tt', ['darkblue', 'cyan', 'yellow', 'red'])\n", |
| 521 | + "tt_cmap = LinearSegmentedColormap.from_list('tt', ['#08306b', '#2171b5', '#fee08b', '#d73027'])\n", |
525 | 522 | "vmin, vmax = np.nanpercentile(tt_vals[np.isfinite(tt_vals)], [2, 98])\n", |
526 | 523 | "\n", |
527 | 524 | "fig, ax = plt.subplots(figsize=(10, 7.5))\n", |
528 | 525 | "hillshade.plot.imshow(ax=ax, cmap='gray', add_colorbar=False)\n", |
529 | | - "tt.plot.imshow(ax=ax, cmap=tt_cmap, alpha=160/255, vmin=vmin, vmax=vmax,\n", |
| 526 | + "tt.plot.imshow(ax=ax, cmap=tt_cmap, alpha=0.75, vmin=vmin, vmax=vmax,\n", |
530 | 527 | " add_colorbar=True,\n", |
531 | 528 | " cbar_kwargs={'label': 'Travel time', 'shrink': 0.7})\n", |
532 | 529 | "ax.set_axis_off()\n", |
|
539 | 536 | "id": "tt-compare", |
540 | 537 | "metadata": { |
541 | 538 | "execution": { |
542 | | - "iopub.execute_input": "2026-03-12T15:58:22.422157Z", |
543 | | - "iopub.status.busy": "2026-03-12T15:58:22.422049Z", |
544 | | - "iopub.status.idle": "2026-03-12T15:58:22.432903Z", |
545 | | - "shell.execute_reply": "2026-03-12T15:58:22.432326Z" |
| 539 | + "iopub.execute_input": "2026-03-13T02:48:21.481411Z", |
| 540 | + "iopub.status.busy": "2026-03-13T02:48:21.481303Z", |
| 541 | + "iopub.status.idle": "2026-03-13T02:48:21.491759Z", |
| 542 | + "shell.execute_reply": "2026-03-13T02:48:21.491111Z" |
546 | 543 | } |
547 | 544 | }, |
548 | 545 | "outputs": [], |
|
585 | 582 | "id": "final-map", |
586 | 583 | "metadata": { |
587 | 584 | "execution": { |
588 | | - "iopub.execute_input": "2026-03-12T15:58:22.434071Z", |
589 | | - "iopub.status.busy": "2026-03-12T15:58:22.433972Z", |
590 | | - "iopub.status.idle": "2026-03-12T15:58:23.394311Z", |
591 | | - "shell.execute_reply": "2026-03-12T15:58:23.393510Z" |
| 585 | + "iopub.execute_input": "2026-03-13T02:48:21.493197Z", |
| 586 | + "iopub.status.busy": "2026-03-13T02:48:21.493089Z", |
| 587 | + "iopub.status.idle": "2026-03-13T02:48:22.232191Z", |
| 588 | + "shell.execute_reply": "2026-03-13T02:48:22.231319Z" |
592 | 589 | } |
593 | 590 | }, |
594 | 591 | "outputs": [], |
595 | 592 | "source": [ |
596 | 593 | "# Final composite: 10 m flood scenario\n", |
597 | | - "import os as _os\n", |
598 | | - "\n", |
599 | 594 | "depth_10m = flood_depth(hand_raster, water_level=10)\n", |
600 | 595 | "\n", |
601 | 596 | "n_flooded = int(np.sum(~np.isnan(depth_10m.values)))\n", |
602 | 597 | "pct_flooded = 100 * n_flooded / (H * W)\n", |
603 | 598 | "print(f\"10 m flood scenario: {n_flooded} cells flooded ({pct_flooded:.1f}% of grid)\")\n", |
604 | 599 | "print(f\"Median depth in flooded area: {np.nanmedian(depth_10m.values):.1f} m\")\n", |
605 | 600 | "\n", |
606 | | - "heat_cmap = LinearSegmentedColormap.from_list('heat', ['lightyellow', 'orange', 'darkred'])\n", |
| 601 | + "depth_cmap = LinearSegmentedColormap.from_list('depth', ['#ffffcc', '#fd8d3c', '#800026'])\n", |
607 | 602 | "\n", |
608 | 603 | "fig, ax = plt.subplots(figsize=(10, 7.5))\n", |
609 | 604 | "hillshade.plot.imshow(ax=ax, cmap='gray', add_colorbar=False)\n", |
610 | | - "dem.plot.imshow(ax=ax, cmap='terrain', alpha=0.5, add_colorbar=False)\n", |
611 | | - "depth_10m.plot.imshow(ax=ax, cmap=heat_cmap, alpha=200/255, add_colorbar=True,\n", |
| 605 | + "depth_10m.plot.imshow(ax=ax, cmap=depth_cmap, alpha=0.85, add_colorbar=True,\n", |
612 | 606 | " cbar_kwargs={'label': 'Flood depth (m)', 'shrink': 0.7})\n", |
613 | | - "streams.plot.imshow(ax=ax, cmap='Blues', alpha=100/255, add_colorbar=False,\n", |
| 607 | + "streams.plot.imshow(ax=ax, cmap='Blues', alpha=0.5, add_colorbar=False,\n", |
614 | 608 | " norm=LogNorm(vmin=stream_vmin))\n", |
615 | | - "ax.legend(handles=[Patch(facecolor='darkorange', alpha=0.78, label='Flood depth'),\n", |
616 | | - " Patch(facecolor='steelblue', alpha=0.39, label='Stream network')],\n", |
| 609 | + "ax.legend(handles=[Patch(facecolor='#fd8d3c', label='Flood depth'),\n", |
| 610 | + " Patch(facecolor='steelblue', alpha=0.5, label='Stream network')],\n", |
617 | 611 | " loc='lower right', fontsize=11, framealpha=0.9)\n", |
618 | 612 | "ax.set_axis_off()\n", |
619 | 613 | "plt.tight_layout()\n", |
620 | 614 | "\n", |
621 | 615 | "# Save preview image\n", |
622 | | - "_os.makedirs('images', exist_ok=True)\n", |
623 | 616 | "import pathlib\n", |
624 | 617 | "pathlib.Path('images').mkdir(exist_ok=True)\n", |
625 | 618 | "fig.savefig('images/flood_analysis_preview.png', bbox_inches='tight', dpi=120)" |
|
0 commit comments