Skip to content
Research Atlas

Spatial Analysis & GIS · Lesson 4 of 4

Ordinary Kriging

~20 min

The Concept

With the variogram fitted, you have everything needed for ordinary kriging (a smart way of estimating a value at an unmeasured spot by carefully weighing all the nearby known measurements): an estimate of how spatial correlation decays with distance, and a set of known well values. Kriging combines these to predict nitrate at any unmonitored point, not by a simple distance-weighted average, but by solving a small system of equations that optimally weights each well according to both its distance from the prediction point and its correlation with all the other wells.

The result is a complete nitrate map of the aquifer, and crucially, a matching uncertainty map showing exactly where your predictions are reliable and where they're speculative. The policymaker who asked about the gap between GW-14 and GW-06 now has her answer.

What makes kriging 'optimal' is that the weights it assigns to each well are chosen to minimise the expected prediction error, the kriging variance. A well directly adjacent to the prediction point gets high weight. A well far away gets low weight. But also: a well that's positioned close to another well provides less unique information, so it's down-weighted relative to a well that 'covers' a different part of the basin.

The kriging standard error at each prediction point gives you the uncertainty of that prediction. Near a well, the standard error is small. In the middle of a large monitoring gap, like between GW-14 and GW-06, the standard error is large. This is not a failure of kriging; it's an honest quantification of what you don't know.

The Analogy

Picture guessing the temperature at a spot on a map using three nearby weather stations. You would not just average the three numbers evenly, you would give more weight to the closest station and less to the ones farther away or clustered together telling you the same thing twice. Kriging is that weighting process, done with exact math instead of a gut feeling.

The Math (optional)

Ordinary kriging finds weights λ_i for each well that minimise prediction variance, subject to the constraint that the weights sum to 1:

Kriging prediction

z^(x0)=i=1nλiz(xi)\hat{z}(x_0) = \sum_{i=1}^{n} \lambda_i z(x_i)

The prediction at unmonitored location x₀ is a weighted average of the n well values z(x_i). The weights λ_i are not arbitrary, they're computed from the variogram.

Kriging variance (uncertainty)

σK2(x0)=c0+c1i=1nλiγ(xi,x0)\sigma^2_K(x_0) = c_0 + c_1 - \sum_{i=1}^{n} \lambda_i \gamma(x_i, x_0)

σ²_K is the prediction uncertainty at x₀. It equals the sill minus the weighted sum of semivariances between x₀ and each well. Points far from all wells, or in clusters of closely-spaced wells, have higher uncertainty.

Try It

Hover each well to see its influence radius. The colour map shows predicted nitrate, note how uncertainty would be highest in the gaps between wells.

010203040506070809101112131415

How far each well's influence extends — the kriging "range" parameter. Larger = smoother, but more likely to blur real gradients.

How steeply influence falls with distance. High power = only the nearest wells contribute; low power = distant wells still matter.

2 mg/L
14 mg/L

Hover a well to see its influence radius. The colour surface predicts nitrate concentration between wells — this is spatial interpolation. The GW-14 hotspot (northeast) drives the red region around the agricultural zone.

Code (optional)

kriging.pypython
from pykrige.ok import OrdinaryKriging
import numpy as np

# Fit ordinary kriging using the exponential variogram we built
OK = OrdinaryKriging(
    wells_gdf["x_utm"],
    wells_gdf["y_utm"],
    wells_gdf["nitrate_mgl"],
    variogram_model="exponential",
    variogram_parameters={
        "psill": 12.8,   # sill from our variogram fit
        "range": 4200,   # range in metres
        "nugget": 1.1,   # nugget from our variogram fit
    },
    verbose=False,
)

# Predict on a fine grid over the basin
x_grid = np.linspace(x_min, x_max, 100)
y_grid = np.linspace(y_min, y_max, 100)
z_pred, z_var = OK.execute("grid", x_grid, y_grid)

print("Mean predicted nitrate:", z_pred.mean().round(2), "mg/L")
print("Max kriging std error: ", np.sqrt(z_var).max().round(3))
# z_var is kriging variance; sqrt gives standard error in same units as nitrate

Line by line

  • OrdinaryKriging takes the well coordinates, values, and pre-fitted variogram parameters.
  • execute('grid', ...) predicts over every point on the 100×100 grid covering the basin.
  • z_pred is the nitrate surface; z_var is the kriging variance at every grid point, the square root gives standard error in mg/L.
  • Large z_var values identify monitoring gaps, locations where adding a new well would most reduce prediction uncertainty.

Why Real Researchers Care

Kriging maps and their associated uncertainty surfaces are standard outputs in hydrogeological contamination assessments. Regulatory bodies often require both the predicted concentration map and the standard error map before deciding whether remediation is warranted, because a prediction of 'contaminated' with high uncertainty warrants more sampling before expensive intervention.

Quick Check

Q1. What does a high kriging standard error at a prediction point mean?

Your Goal

Using the kriging simulation, identify the location in Bluewater Basin where adding a single new well would most reduce prediction uncertainty, describe its position relative to existing wells.

Hint: Look for the largest gap between existing wells in the part of the basin with the highest predicted nitrate concentrations.

Teach It Back

A policymaker asks 'how confident are you in the nitrate prediction for the area between GW-14 and GW-06?' Explain kriging uncertainty in plain language.

Previous lesson