How to Count Eruptions by Volcanic Explosivity Index
On this page
Problem statement
The Volcanic Explosivity Index rates an eruption from 0 to 8 by how much it threw out and how high: each step up means roughly ten times more ejected material. Kilauea's lava flows are VEI 0 or 1, Mount St Helens in 1980 was a 5, Pinatubo in 1991 a 6, Tambora in 1815 a 7. The Smithsonian's eruption table gives the index for most eruptions since 1900 and many before, so you can count how often each size happens and list the largest. The counts need two decisions: which eruptions to include, since uncertain ones carry an index too, and over which years, since small eruptions before the twentieth century mostly went unrecorded. This page counts confirmed eruptions by VEI.
Quick answer
Keep confirmed eruptions with an index, then count by VEI:
c = eru[(eru.Activity_Type == "Confirmed Eruption") & eru.ExplosivityIndexMax.notna()]
print(c.ExplosivityIndexMax.astype(int).value_counts().sort_index().to_string())
print(f"confirmed eruptions with a VEI: {len(c):,}; without: {((eru.Activity_Type == 'Confirmed Eruption') & eru.ExplosivityIndexMax.isna()).sum():,}")
ExplosivityIndexMax
0 809
1 1276
2 3756
3 1150
4 516
5 181
6 52
7 7
confirmed eruptions with a VEI: 7,747; without: 2,169
7,747 confirmed eruptions have an index. VEI 2, a moderate explosive eruption with a column a few kilometres high, is the most common, 3,756 of them, while 52 are VEI 6 and 7 are VEI 7. The counts over all years mix very different periods of record, which is what the next step deals with.
How often each size happens
1. A period where the record is complete enough
for start in [1500, 1800, 1900, 1950]:
s = c[c.StartDateYear >= start]
print(start, s.ExplosivityIndexMax.astype(int).value_counts().sort_index().reindex(range(8), fill_value=0).tolist())
1500 [496, 1232, 3444, 785, 186, 34, 7, 1]
1800 [437, 1181, 2908, 585, 118, 17, 4, 1]
1900 [348, 1060, 1879, 450, 83, 10, 3, 0]
1950 [261, 851, 1057, 339, 57, 7, 1, 0]
Each list counts VEI 0 to 7 from a start year. Since 1500 there have been 34 VEI 5 eruptions and 7 VEI 6. Since 1900 there have been 10 and 3, and since 1950, 7 and 1. A large eruption is noticed and written down in any century, so its count grows roughly with the length of the period. A small one is recorded only once someone is watching, so its count is concentrated in recent decades. For a rate, take each size from a period in which its record is complete.
2. Eruptions per decade since 1900
s = c[(c.StartDateYear >= 1900) & (c.StartDateYear < 2020)]
per_decade = s.ExplosivityIndexMax.astype(int).value_counts().sort_index() / 12
print(per_decade.round(2).to_string())
ExplosivityIndexMax
0 26.75
1 82.67
2 151.50
3 35.92
4 6.42
5 0.75
6 0.25
Over 1900 to 2019, the world had about 151 VEI 2 eruptions a decade, 36 of VEI 3 and 6.4 of VEI 4, one VEI 5 every 13 years or so, and three VEI 6 in 120 years: Santa MarΓa in 1902, Novarupta in 1912 and Pinatubo in 1991.
3. Each step rarer
r = per_decade[per_decade.index >= 2]
print((r / r.shift(-1)).dropna().round(1).to_string())
ExplosivityIndexMax
2 4.2
3 5.6
4 8.6
5 3.0
Each step up the index is between 3 and 9 times rarer, not the factor of ten the definition suggests for erupted volume. The index steps by volume, but how often each size happens is a property of volcanoes, not of the scale, and the largest classes rest on so few events that their ratios are rough.
The largest eruptions
The data used on this page
The Smithsonian Institution Global Volcanism Program's Volcanoes of the World database (version 5.3 is cited as doi:10.5479/si.GVP.VOTW5-2025.5.3): its Holocene volcano and eruption tables, read from the program's WFS service on 19 October 2026 and saved on this site, because the database is edited as eruptions are reported.
from pathlib import Path
import zipfile
import geopandas as gpd
import numpy as np
import pandas as pd
import requests
Path("data").mkdir(exist_ok=True)
# Smithsonian Global Volcanism Program, Volcanoes of the World: Holocene volcanoes, Holocene eruptions and Pleistocene
# volcanoes as GeoJSON from its WFS service, with Natural Earth's populated places and 1:110m countries.
# Saved 19 October 2026, because the database is edited as eruptions are reported.
# Live: https://webservices.volcano.si.edu/geoserver/GVP-VOTW/ows?service=WFS&version=2.0.0&request=GetFeature
# &outputFormat=json&typeName=GVP-VOTW:Smithsonian_VOTW_Holocene_Volcanoes (and ..._Holocene_Eruptions)
ARCHIVE = "gvp-votw-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}")
vol = gpd.read_file(Z.open("Smithsonian_VOTW_Holocene_Volcanoes.json"))
eru = gpd.read_file(Z.open("Smithsonian_VOTW_Holocene_Eruptions.json"))
print(f"Volcanoes of the World: {len(vol):,} Holocene volcanoes, {len(eru):,} eruptions")
Volcanoes of the World: 1,214 Holocene volcanoes, 11,089 eruptions
Example 1: VEI 6 and 7
big = c[c.ExplosivityIndexMax >= 6].sort_values("StartDateYear")
print(f"VEI 7: {(big.ExplosivityIndexMax == 7).sum()}; VEI 6: {(big.ExplosivityIndexMax == 6).sum()}")
print(big[big.ExplosivityIndexMax == 7][["Volcano_Name", "StartDateYear", "StartEvidenceMethod"]].to_string(index=False))
print(big[(big.ExplosivityIndexMax == 6) & (big.StartDateYear >= 1500)][["Volcano_Name", "StartDateYear"]].to_string(index=False))
VEI 7: 7; VEI 6: 52
Volcano_Name StartDateYear StartEvidenceMethod
Kurile Lake -6440 Isotopic: 14C (calibrated)
Crater Lake -5680 Sidereal: Ice Core
Kikai -4350 Isotopic: 14C (uncalibrated)
Blanco, Cerro -2300 Isotopic: 14C (calibrated)
Santorini -1610 Isotopic: 14C (calibrated)
Rinjani 1257 Sidereal: Ice Core
Tambora 1812 Observations: Reported
Volcano_Name StartDateYear
Billy Mitchell 1580
Huaynaputina 1600
Long Island 1660
Krakatau 1883
Santa Maria 1902
Novarupta 1912
Pinatubo 1991
The seven VEI 7 eruptions are the largest of the last 10,000 years: Kurile Lake in Kamchatka, Crater Lake (Mount Mazama) in Oregon, Kikai in Japan, Cerro Blanco in Argentina, Santorini, Rinjani (Samalas) in 1257 and Tambora. Tambora's year is 1812, when that eruptive period began, not the climactic eruption of April 1815, because the table dates the start of an eruption. Five of the seven are dated from radiocarbon or ice cores.
Example 2: the index of uncertain eruptions
u = eru[eru.Activity_Type == "Uncertain Eruption"]
print(f"uncertain eruptions: {len(u):,}; with a VEI: {u.ExplosivityIndexMax.notna().sum()}")
print(u.ExplosivityIndexMax.value_counts().sort_index().to_string())
uncertain eruptions: 1,173; with a VEI: 671
ExplosivityIndexMax
0.0 210
1.0 165
2.0 274
3.0 22
671 of the 1,173 uncertain eruptions also carry an index, mostly small. Count only confirmed eruptions unless you mean to include reports that may not have been eruptions at all.
Internal links
- What the records hold β the index and the evidence behind it
- An eruption record filling in β why step 1 matters
- How long eruptions last β duration by explosivity
- Gutenberg-Richter for earthquakes β the same kind of size-frequency count for earthquakes