4.3 Cyclones

Extratropical cyclones are large low-pressure systems that dominate mid-latitude weather. They form along fronts where contrasting air masses meet.

Norwegian Cyclone Model

Stage 1: Initial Perturbation

Small wave forms on polar front. Pressure begins falling.

Stage 2: Development

Wave amplifies, cold and warm fronts develop. Warm sector evident.

Stage 3: Mature

Strongest intensity. Cold front catching up to warm front.

Stage 4: Occlusion & Decay

Cold front overtakes warm front. System fills and weakens.

Cyclone Structure

Warm Sector

Southerly flow, warm moist air

Cold Sector

NW flow, cold dry air

Triple Point

Junction of cold, warm, occluded fronts

Python: Cyclone Evolution

#!/usr/bin/env python3
"""
cyclones.py - Extratropical cyclone visualization

Run: python3 cyclones.py
Requires: pip install numpy matplotlib
"""
import numpy as np
import matplotlib.pyplot as plt

# Create a simplified cyclone pressure field
def cyclone_pressure(X, Y, x0, y0, central_p, radius):
    """Generate pressure field for a cyclone"""
    r = np.sqrt((X - x0)**2 + (Y - y0)**2)
    p = central_p + (1013 - central_p) * (1 - np.exp(-r**2 / radius**2))
    return p

# Grid
nx, ny = 100, 100
x = np.linspace(-2000, 2000, nx)
y = np.linspace(-2000, 2000, ny)
X, Y = np.meshgrid(x, y)

# Create four stages of cyclone development
fig, axes = plt.subplots(2, 2, figsize=(14, 12))

stages = [
    {'name': 'Stage 1: Initial', 'central_p': 1005, 'radius': 500},
    {'name': 'Stage 2: Developing', 'central_p': 995, 'radius': 600},
    {'name': 'Stage 3: Mature', 'central_p': 975, 'radius': 700},
    {'name': 'Stage 4: Occluded', 'central_p': 985, 'radius': 800},
]

for ax, stage in zip(axes.flat, stages):
    p = cyclone_pressure(X, Y, 0, 0, stage['central_p'], stage['radius'])

    # Plot isobars
    cs = ax.contour(X, Y, p, levels=np.arange(970, 1020, 4), colors='black')
    ax.clabel(cs, inline=True, fontsize=8)

    # Add fronts (simplified)
    theta = np.linspace(0, np.pi, 50)
    # Cold front (blue triangles)
    cf_x = stage['radius'] * 0.8 * np.cos(theta - 0.5)
    cf_y = stage['radius'] * 0.8 * np.sin(theta - 0.5)
    ax.plot(cf_x, cf_y, 'b-', linewidth=3)
    for i in range(0, len(cf_x), 5):
        ax.scatter(cf_x[i], cf_y[i], marker='^', s=80, c='blue')

    # Warm front (red semicircles)
    wf_x = stage['radius'] * 0.6 * np.cos(theta + 1)
    wf_y = stage['radius'] * 0.6 * np.sin(theta + 1)
    ax.plot(wf_x, wf_y, 'r-', linewidth=3)
    for i in range(0, len(wf_x), 5):
        ax.scatter(wf_x[i], wf_y[i], marker='o', s=80, c='red')

    ax.set_xlabel('Distance (km)')
    ax.set_ylabel('Distance (km)')
    ax.set_title(f"{stage['name']} (Central P: {stage['central_p']} hPa)")
    ax.set_aspect('equal')
    ax.annotate('L', (0, 0), fontsize=20, fontweight='bold', color='red', ha='center')

    # Add wind arrows
    skip = 10
    # Simplified cyclonic flow
    u = Y[::skip, ::skip] / 500
    v = -X[::skip, ::skip] / 500
    ax.quiver(X[::skip, ::skip], Y[::skip, ::skip], u, v, alpha=0.5, scale=20)

plt.tight_layout()
plt.savefig('cyclones.png', dpi=150, bbox_inches='tight')
plt.show()

# Cyclone intensity scale
print("Extratropical Cyclone Intensity:")
print("-" * 40)
print("Weak:     Central pressure > 1000 hPa")
print("Moderate: Central pressure 980-1000 hPa")
print("Strong:   Central pressure 960-980 hPa")
print("Intense:  Central pressure < 960 hPa")
print()
print("Typical lifecycle: 3-7 days")
print("Typical diameter: 1000-3000 km")
print("Movement: West to East at ~30-50 km/h")