Earth Data School/Trends: Theil–Sen & Mann–Kendall
Lesson 3.2 · 7 of 17

Trends: Theil–Sen & Mann–Kendall

Almost every climate question is really one question: is this going up or down over time — and is the change real, or just luck? Here's the robust way to answer it, the way /verify does.

In one lineTheil–Sen finds the trend's slope in a way that one freak year can't ruin. Mann–Kendall tells you whether that slope is more than chance. Together: a rate, and a yes/no on "is it real?".

The problem with the obvious method

The line you learned in school — least-squares regression — finds the slope that minimises the squared distance to every point. It works, but it's fragile: because it squares the errors, a single outlier (one weird year — a sensor glitch, an El Niño spike) can yank the whole line toward it. In climate records, weird years happen. So we want a slope that doesn't panic at outliers.

Theil–Sen: the median of every slope

The idea is almost laughably simple. Take every pair of points, draw the line between them, and write down its slope. With 24 years that's ~276 little slopes. The Theil–Sen estimate is just the median of all of them.

slope = median over all pairs (i,j) of (yⱼ − yᵢ) / (xⱼ − xᵢ)

Because the median ignores extremes, a couple of bad years barely move it — you'd have to corrupt nearly half the data to break it. That robustness is why it's the standard for environmental trends.

Mann–Kendall: is the trend real?

A non-zero slope isn't enough — random noise also has a slope. Mann–Kendall asks a rank question: for every later year, is it usually higher (or lower) than the earlier years? It adds +1 for each later-and-higher pair, −1 for later-and-lower, and sums them into a score S. A big |S| relative to what noise would produce → a small p-value → "significant". It's non-parametric (no assumption the data is bell-curved), which suits messy climate series.

Significance ≠ importanceA tiny slope can be "significant" (very steady) and still not matter; a big slope can be "not significant" (too noisy to be sure). Always read the rate and the p-value together — exactly what the cards on /verify show.

Play with it

Drag the sliders. Watch the robust Theil–Sen line (gold) barely flinch when you add an outlier, while least-squares (grey dashed) lurches. Turn the noise up until Mann–Kendall stops calling it significant.

Theil–Sen: /yr least-squares: /yr Mann–Kendall p:

Do it yourself — run it right here

You don't implement these by hand — two well-tested libraries do. This is exactly what runs server-side for a /verify trend. Hit Run, then change the noise and rerun until Mann–Kendall stops calling it significant:

editable · runs in your browser

The honest caveat

Mann–Kendall assumes each year is independent. Climate years are often autocorrelated (a wet year nudges the next), which makes the basic p-value optimistic — it can call things significant a touch too readily. The grown-up fix is a variance correction (e.g. Hamed–Rao). The /verify cards note this; it's the difference between "computed" and a number you'd stake a paper on.