Tsunamis Counted in the Wrong Country: The Event Is Where the Source Was

On this page

Problem statement

Count NOAA's tsunami events by country and the Indian Ocean tsunami of 2004 belongs to Indonesia, though most of its victims died in Sri Lanka, India and Thailand, and the 1960 Chilean tsunami that killed people in Hawaii and Japan belongs to Chile. An event's country and coordinates are those of its source: the earthquake's epicentre, the volcano, the landslide. Where the tsunami struck is in the run-up table, one row per place. A country's tsunami history, its deaths and its most dangerous sources all come from run-ups. This page counts both ways and shows how far apart they are.

Quick answer

Count events by country, then count distinct events that reached each country through its run-ups:

sure = ev[ev.eventValidity >= 3]
by_source = sure.country.value_counts()
reached = ru[ru.tsunamiEventId.isin(sure.id)].groupby("country").tsunamiEventId.nunique()
t = pd.DataFrame({"as_source": by_source, "reached_by": reached}).fillna(0).astype(int)
print(t.sort_values("reached_by", ascending=False).head(8).to_string())
               as_source  reached_by
country                             
JAPAN                303         402
USA                  135         270
INDONESIA            135         138
USA TERRITORY         13         134
CHILE                 65         105
VANUATU               39         102
RUSSIA                85          99
MEXICO                53          90

Japan is the source of 303 probable or definite tsunamis and was reached by 402. The United States is the source of 135 and was reached by 270, with another 134 reaching its Pacific territories, though only 13 started there. Vanuatu was the source of 39 and reached by 102. Counting by event country measures where tsunamis start. Counting by run-up measures where they arrive.

Paired bars by country of tsunamis starting there and tsunamis reaching it: Japan 303 and 402, United States 135 and 270, US territories 13 and 134. Paired bars by country of tsunamis starting there and tsunamis reaching it: Japan 303 and 402, United States 135 and 270, US territories 13 and 134.
Counting by source and by where tsunamis arrived.

Source country, struck country

1. Tsunamis from abroad

j = ru.merge(sure[["id", "country"]], left_on="tsunamiEventId", right_on="id", suffixes=("", "_source"))
foreign = j[j.country != j.country_source]
print(f"run-ups in another country than the source: {len(foreign):,} of {len(j):,}")
print(foreign.groupby("country").tsunamiEventId.nunique().nlargest(5).to_string())
run-ups in another country than the source: 11,631 of 33,734
country
USA              140
USA TERRITORY    121
JAPAN            111
CANADA            70
VANUATU           68

11,631 of 33,734 run-ups, about a third, are in a different country from the event's source. The United States was reached by 140 foreign tsunamis and its territories by 121, Japan by 111 and Canada by 70.

2. Deaths where they happened

d = j.groupby(["country_source", "country"]).deaths.sum()
print(d[d > 1000].sort_values(ascending=False).head(8).astype(int).to_string())
country_source  country  
INDONESIA       INDONESIA    223351
JAPAN           JAPAN        130459
PORTUGAL        PORTUGAL      63000
INDONESIA       SRI LANKA     35333
                INDIA         26047
PORTUGAL        MOROCCO       10000
INDONESIA       THAILAND       8212
CHILE           CHILE          6668

Summed by source and struck country, Indonesia's tsunamis killed 223,351 people in Indonesia but also 35,333 in Sri Lanka, 26,047 in India and 8,212 in Thailand. Portugal's killed 10,000 in Morocco, from the Lisbon earthquake of 1755. An event table credits all of these to the source country.

Horizontal bars of tsunami deaths in another country than the source: Indonesia to Sri Lanka 35,333, to India 26,047, Portugal to Morocco 10,000, Indonesia to Thailand 8,212. Horizontal bars of tsunami deaths in another country than the source: Indonesia to Sri Lanka 35,333, to India 26,047, Portugal to Morocco 10,000, Indonesia to Thailand 8,212.
Tsunami deaths abroad.

3. A source country's reach

print(j[j.country_source == "CHILE"].groupby("country").tsunamiEventId.nunique().nlargest(6).to_string())
country
CHILE               64
USA                 20
JAPAN               14
PERU                14
FRENCH POLYNESIA    11
SAMOA                9

Chile's tsunamis reached Chile itself in 64 events, and the United States in 20, Japan and Peru in 14 each, French Polynesia in 11 and Samoa in 9: a Chilean earthquake is a Pacific-wide event.

Per country, both ways

The data used on this page

NOAA's Global Historical Tsunami Database from the National Centers for Environmental Information (doi:10.7289/V5PN93H7), public domain: every event and run-up from its HazEL API, downloaded on 19 October 2026 and saved on this site, because records are added and revised. Heights are in metres and distances in kilometres.

from pathlib import Path
import json
import zipfile

import geopandas as gpd
import numpy as np
import pandas as pd
import requests

Path("data").mkdir(exist_ok=True)
# NOAA NCEI Global Historical Tsunami Database (doi:10.7289/V5PN93H7): every event and every run-up from the HazEL API,
# with Natural Earth's 1:50m land and 1:110m countries. Saved 19 October 2026: events and run-ups are added and revised.
# Live: https://www.ngdc.noaa.gov/hazel/hazard-service/api/v1/tsunamis/events?page=1 (and .../runups), 200 a page
ARCHIVE = "ncei-tsunami-2026-10-19.zip"
if not Path(f"data/{ARCHIVE}").exists():
    Path(f"data/{ARCHIVE}").write_bytes(requests.get(f"https://data.spatialworkflow.io/{ARCHIVE}", timeout=600).content)
Z = zipfile.ZipFile(f"data/{ARCHIVE}")
ev = pd.DataFrame(json.loads(Z.read("tsunami-events.json")))
ru = pd.DataFrame(json.loads(Z.read("tsunami-runups.json")))
print(f"NCEI tsunami database: {len(ev):,} events, {len(ru):,} run-ups")
NCEI tsunami database: 3,138 events, 35,129 run-ups

Example 1: deaths by struck country

print(j.groupby("country").deaths.sum().nlargest(6).astype(int).to_string())
country
INDONESIA    223352
JAPAN        130745
PORTUGAL      63000
SRI LANKA     35333
INDIA         26073
MOROCCO       10000

By struck country, Indonesia has 223,352 recorded tsunami deaths, Japan 130,745, Portugal 63,000, Sri Lanka 35,333 and India 26,073. Portugal's 63,000 is more than the 50,000 recorded for the Lisbon event itself: run-ups at neighbouring places can each carry a figure for the same deaths. Run-up deaths show where people died, but their sum is not always a clean total.

Horizontal bars of Chilean tsunamis with a run-up in each country: Chile 64, United States 20, Japan and Peru 14, French Polynesia 11. Horizontal bars of Chilean tsunamis with a run-up in each country: Chile 64, United States 20, Japan and Peru 14, French Polynesia 11.
Where Chile's tsunamis were recorded.

Example 2: events whose deaths are recorded only on the event

recorded = j.groupby("tsunamiEventId").deaths.sum()
gap = sure.set_index("id").deaths.sub(recorded, fill_value=0)
print(f"events whose run-up deaths add up to less than the event's: {(gap > 0).sum()}; deaths not assigned to a place: {gap[gap > 0].sum():,.0f}")
events whose run-up deaths add up to less than the event's: 80; deaths not assigned to a place: 84,523

80 events have fewer deaths in their run-ups than on the event, and 84,523 deaths in all are not assigned to any place. Neither table alone gives a complete death count by country. Use run-ups for where, the event for how many, and say which.