Global seismicity map — one year of M5+¶
Map a full year of global M5+ earthquakes from USGS, with marker area scaled by magnitude and colour by hypocentre depth — the classic view that traces the plate boundaries.
Setup¶
The imports up front: Path for the scratch output directory, matplotlib for the map, and the unified EarthLens entry point. FDSN is a vector backend, so download() returns a GeoDataFrame of events.
from pathlib import Path
import matplotlib.pyplot as plt
from earthlens import EarthLens
OUT_DIR = Path('fdsn_output')
OUT_DIR.mkdir(exist_ok=True)
Query one year of global M5+ events¶
First build the request — source, catalogue (variables), the 2023 date window, a whole-globe bounding box, and a magnitude floor. Keeping construction on its own line makes the parameters easy to read and tweak.
quake = EarthLens(
variables=['USGS'],
data_source='fdsn',
start='2023-01-01',
end='2023-12-31',
aoi=[-180, -90, 180, 90],
min_magnitude=5.0,
path=str(OUT_DIR),
)
The download() call performs the live FDSN query and returns the events into memory. It is wrapped in a try/except so the notebook degrades gracefully (rather than erroring) when run offline.
events = None
try:
events = quake.download()
print(f'{len(events)} M5+ events in 2023')
except Exception as exc:
print(f'live FDSN query skipped (offline?): {type(exc).__name__}: {exc}')
Magnitude-scaled, depth-coloured scatter¶
Plot each epicentre with marker area growing as 2 ** magnitude and colour set by hypocentre depth, so the deep subduction-zone events stand out from the shallow ridge seismicity. The plot is guarded on a successful download.
if events is not None and len(events):
fig, ax = plt.subplots(figsize=(12, 6))
sc = ax.scatter(
events['longitude'],
events['latitude'],
s=2 ** events['magnitude'],
c=events['depth_km'],
cmap='viridis_r',
alpha=0.6,
edgecolor='none',
)
fig.colorbar(sc, ax=ax, label='depth (km)')
ax.set_title('Global M5+ seismicity, 2023 (marker area ~ magnitude)')
ax.set_xlabel('longitude')
ax.set_ylabel('latitude')
ax.set_xlim(-180, 180)
ax.set_ylim(-90, 90)