8.5 Paleoceanography
Paleoceanography reconstructs past ocean conditions from geological and geochemical proxies. It reveals how oceans responded to past climate changes and helps predict future changes.
Proxy Records
δ¹⁸O (Oxygen Isotopes)
In foram shells. Records ice volume + temperature. Primary climate proxy.
Mg/Ca Ratio
In foram calcite. Temperature-dependent. Separates T from ice volume.
δ¹³C (Carbon Isotopes)
Nutrient cycling, productivity, circulation. Traces water masses.
Alkenones
Organic molecules from coccolithophores. SST reconstruction.
Key Past Events
Ice Ages (Pleistocene)
100 kyr cycles. Sea level ±120m. THC shutdowns. Orbital forcing (Milankovitch).
PETM (56 Ma)
Paleocene-Eocene Thermal Maximum. +5°C. Massive carbon release. Ocean acidification.
OAEs (Oceanic Anoxic Events)
Cretaceous. Widespread oxygen depletion. Black shale deposition. Mass extinctions.
Oxygen Isotope Stratigraphy
\( \delta^{18}O = \left( \frac{(^{18}O/^{16}O)_{sample}}{(^{18}O/^{16}O)_{standard}} - 1 \right) \times 1000 \)
Higher δ¹⁸O = more ice, colder oceans
Marine Isotope Stages (MIS) define glacial/interglacial periods back millions of years.
Python: Benthic δ¹⁸O
#!/usr/bin/env python3
"""paleoceanography.py - Oxygen isotope record"""
import numpy as np
import matplotlib.pyplot as plt
def synthetic_d18O(time_ka, glacial_amplitude=1.5, interglacial=3.0):
"""
Synthetic benthic δ18O record with ~100 kyr cycles
"""
# 100 kyr eccentricity cycle (dominant)
eccentricity = glacial_amplitude * np.sin(2 * np.pi * time_ka / 100)
# 41 kyr obliquity
obliquity = 0.5 * np.sin(2 * np.pi * time_ka / 41)
# 23 kyr precession
precession = 0.3 * np.sin(2 * np.pi * time_ka / 23)
d18O = interglacial + eccentricity + obliquity + precession
# Add sawtooth character (slow cooling, rapid warming)
d18O += 0.3 * np.sin(2 * np.pi * time_ka / 100 + 0.5)
return d18O
# Last 800 kyr (ice core era)
time = np.linspace(0, 800, 1000)
d18O = synthetic_d18O(time)
plt.figure(figsize=(12, 5))
plt.plot(time, d18O, 'b-', lw=1)
plt.fill_between(time, d18O, 3.0, where=d18O > 3.5, alpha=0.3, color='lightblue',
label='Glacial')
plt.fill_between(time, d18O, 3.0, where=d18O < 3.5, alpha=0.3, color='orange',
label='Interglacial')
plt.xlabel('Age (ka BP)')
plt.ylabel('δ¹⁸O (‰)')
plt.title('Synthetic Benthic Oxygen Isotope Record')
plt.gca().invert_yaxis() # Convention: more positive = glacial
plt.gca().invert_xaxis() # Older on right
plt.legend()
plt.grid(True, alpha=0.3)
print("Marine Isotope Stages:")
print(" MIS 1: Current interglacial (Holocene)")
print(" MIS 2: Last Glacial Maximum (~20 ka)")
print(" MIS 5e: Last interglacial (~125 ka, warmer than today)")