FLODIS — linking observed flood footprints to their impacts¶
FLODIS (Mester, Frieler & Schewe, 2023) is the observed hazard-footprint → impact bridge: it matches recorded flood impacts — fatalities, economic damages and human displacements — to the satellite flood footprints that caused them, and enriches each matched event with the affected population, GDP and critical infrastructure.
This notebook teaches the earthlens.flodis backend end to end:
- fetch the two FLODIS tables (
damagesanddisplacement) from the pinned, public Zenodo release, - read and visualise the impact records, and
- see how each table carries the keys to attach the footprints from the backends earthlens already ships.
FLODIS is a tabular backend — download() returns a pandas.DataFrame — and it needs no credentials
(the Zenodo record is public, CC-BY-4.0). See the API reference.
Setup¶
We import the facade and the plotting libraries, and point the downloads at a throwaway directory. The kernel's working directory is this notebook's own folder, so a temp directory keeps the fetched CSVs out of the repository.
import tempfile
from pathlib import Path
import matplotlib.pyplot as plt
import pandas as pd
from earthlens.core import EarthLens
pd.set_option("display.max_columns", 12)
DATA_DIR = Path(tempfile.mkdtemp(prefix="flodis-"))
DATA_DIR
Quickstart — the damages table¶
dataset="damages" (the default) returns the EM-DAT deaths/damages table: one row per flood event that FLODIS
matched to a Global Flood Database footprint, over 2000–2018. Each row keeps the EM-DAT disasterno key.
damages = EarthLens(
"flodis",
dataset="damages",
start="2000",
end="2018",
path=str(DATA_DIR),
).download()
damages.shape
A handful of the most-used columns — the join key, the headline impacts, and the GFD-match count:
damages[
[
"ISO3",
"year",
"disasterno",
"total_deaths",
"total_damages_(000_USD)",
"GFD_matches",
]
].head()
Damages through time¶
Summing the reported economic damages by year shows the record's big flood years. FLODIS reports damages in thousands of USD, so we scale to millions for the axis.
by_year = damages.groupby("year")["total_damages_(000_USD)"].sum().div(1_000)
fig, ax = plt.subplots(figsize=(9, 4))
ax.bar(by_year.index.astype(int), by_year.values, color="#2b6cb0")
ax.set_title("FLODIS matched flood damages by year (2000-2018)")
ax.set_xlabel("year")
ax.set_ylabel("reported damages (million USD)")
plt.show()
Where the fatalities fall¶
The same table carries total_deaths. Ranking countries by their summed matched-event fatalities highlights the
most-affected nations over the period.
top_deaths = damages.groupby("ISO3")["total_deaths"].sum().nlargest(12)
fig, ax = plt.subplots(figsize=(9, 4))
ax.barh(top_deaths.index[::-1], top_deaths.values[::-1], color="#c53030")
ax.set_title("Top 12 countries by FLODIS matched flood fatalities (2000-2018)")
ax.set_xlabel("total deaths")
plt.show()
How well the impacts match a footprint¶
FLODIS records how each impact event was matched to the Global Flood Database in GFD_matches (the number of GFD
events matched) and matching_type. The distribution tells you how many impact events have an observed footprint
behind them.
match_counts = damages["GFD_matches"].value_counts().sort_index()
fig, ax = plt.subplots(figsize=(9, 4))
ax.bar(match_counts.index.astype(int), match_counts.values, color="#2f855a")
ax.set_title("GFD footprints matched per damage event")
ax.set_xlabel("number of matched GFD events")
ax.set_ylabel("count of impact events")
plt.show()
The displacement table¶
dataset="displacement" returns the IDMC human-displacement table, keyed on the GADM GID_1 / GID_2 admin codes
instead of disasterno. Filter it by country= (ISO3) and, optionally, gid= (a GADM code).
displacement = EarthLens(
"flodis",
dataset="displacement",
path=str(DATA_DIR),
).download()
displacement[
["ISO3", "year", "displacements", "GID_1", "GID_2", "num_provinces"]
].head()
Ranking countries by total displaced people shows where flood displacement concentrated over the record:
top_disp = displacement.groupby("ISO3")["displacements"].sum().nlargest(12)
fig, ax = plt.subplots(figsize=(9, 4))
ax.barh(top_disp.index[::-1], top_disp.values[::-1], color="#6b46c1")
ax.set_title("Top 12 countries by FLODIS flood displacements (2000-2018)")
ax.set_xlabel("people displaced")
plt.show()
Attaching the footprints (the join)¶
FLODIS carries the keys to the footprints, not the geometry — earthlens does not re-implement GDIS or the Global Flood Database. You attach the footprints from the backends earthlens already ships. These calls need credentials (an Earthdata Login for GDIS, a Google Earth Engine service account for GFD), so they are shown here for reference rather than run.
GDIS disaster geometry — joined on disasterno, from the emdat
backend:
gdis = EarthLens("emdat", variables=["gdis:points"], country="MOZ").download() # a FeatureCollection
merged = gdis.merge(damages, on="disasterno", how="inner") # FeatureCollection is a GeoDataFrame
Global Flood Database extents — the observed footprints, from the
gee backend:
gfd = EarthLens(
"gee",
dataset="GLOBAL_FLOOD_DB/MODIS_EVENTS/V1",
variables=["flooded"], # the flood-extent band (GEE addresses bands)
start="2000",
end="2018",
aoi=(32.0, -26.0, 41.0, -10.0), # Mozambique bbox
).download()
Together the three layers answer different questions about the same events: FLODIS gives the impact magnitude, GDIS gives the where (admin geometry), and GFD gives the observed flood extent.
Takeaway¶
earthlens.flodisfetches two public, CC-BY tabular impact records over 2000–2018:damages(EM-DAT, keyed ondisasterno) anddisplacement(IDMC, keyed onGID_1/GID_2).- Every row is already matched to a Global Flood Database footprint and enriched with affected population, GDP and infrastructure sums.
- FLODIS carries the join keys so you can attach the footprint geometry from the shipped
emdat(GDIS) andgee(GFD) backends, rather than re-fetching it.
Next: the Usage page for the full filter and join recipes.