GDACS country hazard profile¶
Profile the disaster alerts for a single country over a window using the iso3 / country columns: a breakdown by hazard type and alert level, a bar chart, and the most severe alerts.
GDACS is public — no credentials, no extra to install.
Setup¶
Consolidate the imports up front. earthlens provides the unified EarthLens entry point; pandas and matplotlib are used later for the crosstab and the bar chart.
import datetime as dt
from pathlib import Path
import matplotlib.pyplot as plt
import pandas as pd
from earthlens import EarthLens
Window and target country¶
Pick the country to profile (ISO-3166 alpha-3) and the six-month window. The Philippines (PHL) sees frequent multi-hazard activity — earthquakes, cyclones, floods, volcanoes.
OUT_DIR = Path('gdacs_output')
OUT_DIR.mkdir(exist_ok=True)
TARGET_ISO3 = 'PHL'
TODAY = dt.date.today()
START = (TODAY - dt.timedelta(days=180)).strftime('%Y-%m-%d')
END = TODAY.strftime('%Y-%m-%d')
print('window:', START, 'to', END, '| target:', TARGET_ISO3)
Fetch the alerts¶
Build the GDACS request first, then call download() on it as a separate step. An empty variables list pulls all six hazard types over the whole globe; the try/except lets the notebook skip gracefully when offline.
alerts = None
try:
gdacs = EarthLens(
variables=[], # all six hazard types
data_source='gdacs',
start=START,
end=END,
aoi=[-180, -90, 180, 90],
path=str(OUT_DIR),
)
alerts = gdacs.download()
print(f'{len(alerts)} alerts worldwide')
except Exception as exc:
print(f'live GDACS query skipped (offline?): {type(exc).__name__}: {exc}')
Select the country¶
Filter to the target iso3. If the target had no alerts in the window, fall back to the country with the most alerts so the rest of the notebook always has data.
country = None
if alerts is not None and len(alerts):
country = alerts[alerts['iso3'] == TARGET_ISO3]
label = TARGET_ISO3
if not len(country):
top = alerts['iso3'].dropna().value_counts()
if len(top):
label = top.index[0]
country = alerts[alerts['iso3'] == label]
print(f'{TARGET_ISO3} had no alerts; falling back to {label}')
if country is not None and len(country):
name = country['country'].iloc[0]
print(f'{len(country)} alerts for {name} ({label})')
Breakdown by hazard and alert level¶
Cross-tabulate hazard type against alert level, ensuring every Green / Orange / Red column is present so the table shape is stable.
if country is not None and len(country):
crosstab = pd.crosstab(country['hazard_type'], country['alert_level'])
for level in ['Green', 'Orange', 'Red']:
if level not in crosstab.columns:
crosstab[level] = 0
display(crosstab[['Green', 'Orange', 'Red']])
Alerts by hazard type¶
A bar chart of the per-hazard alert counts for the selected country and window.
if country is not None and len(country):
counts = country['hazard_type'].value_counts().sort_index()
ax = counts.plot(kind='bar', color='steelblue')
ax.set_title(f'Alerts by hazard type — {label}, {START} to {END}')
ax.set_xlabel('hazard type')
ax.set_ylabel('alert count')
plt.tight_layout()
plt.show()
Most severe alerts¶
Sorted by alert score, highest first.
if country is not None and len(country):
cols = [
'from_date',
'hazard_type',
'name',
'alert_level',
'alert_score',
'severity',
'severity_unit',
]
display(country.sort_values('alert_score', ascending=False)[cols].head(10))