Scientific Statistics · Lesson 2 of 7
Confidence Intervals
~16 min
The Concept
Your team reports that the mean nitrate at GW-14 over the last year is 8.7 mg/L. A policymaker asks the obvious question: 'How sure are you it's 8.7 and not 7.2, or 10.1?' The honest scientific answer is a confidence interval, a range of values that almost certainly contains the true population mean.
The WHO drinking water guideline for nitrate is 11.3 mg/L (as NO₃⁻-N). The policymaker needs to know whether the true mean at GW-14 is below that threshold, not just whether the sample mean is below it.
A 95% confidence interval (a range of values you are pretty confident the true answer falls inside) says: if we collected 100 different samples from this well and built a 95% CI from each one, approximately 95 of those intervals would contain the true population mean μ. Any single interval either contains μ or doesn't, but you can be 95% confident before you collect your sample that the procedure will capture it.
The interval is built outward from the sample mean in both directions, by a margin equal to the critical value (from a t-distribution for small samples) multiplied by the standard error.
The Analogy
It is like throwing a ring toss at a peg you can not quite see. A confidence interval is the size of ring you would need to throw so that, if you played the game 100 times, about 95 of your rings would land around the peg. It does not mean any one ring is 95% likely to have landed on the peg, it means your throwing method is reliable 95% of the time.
The Math (optional)
A two-sided 95% confidence interval uses the t-distribution critical value, which depends on degrees of freedom (n-1).
95% Confidence Interval
The interval spans from x̄ minus the margin to x̄ plus the margin. t_{α/2, n-1} is the t critical value for 95% confidence with n-1 degrees of freedom, about 1.96 for large n, slightly larger for small samples.
Code (optional)
import numpy as np
from scipy import stats
nitrate = np.load("gw14_nitrate_year5.npy")
n, xbar, s = len(nitrate), nitrate.mean(), nitrate.std(ddof=1)
se = s / np.sqrt(n)
# 95% CI using t-distribution
alpha = 0.05
t_crit = stats.t.ppf(1 - alpha/2, df=n-1)
margin = t_crit * se
print(f"Mean: {xbar:.3f} mg/L")
print(f"95% CI: ({xbar - margin:.3f}, {xbar + margin:.3f}) mg/L")
print(f"WHO limit: 11.3 mg/L")
print(f"CI entirely below limit: {xbar + margin < 11.3}")Line by line
- stats.t.ppf gives the t critical value for a two-tailed test at the specified α and degrees of freedom.
- The margin = t_crit × SE extends symmetrically in both directions from the mean.
- The key policy question, is the upper bound of the CI still below 11.3?, can be checked directly.
Why Real Researchers Care
Confidence intervals are preferred over bare p-values in most modern environmental science journals, because they communicate both statistical significance and practical magnitude. A very large dataset can yield a p-value of 0.001 for a difference of 0.001 mg/L, statistically significant but environmentally meaningless. The CI shows the actual range of plausible values.
Quick Check
Q1. A 95% CI for mean nitrate at GW-14 is (7.2, 9.8) mg/L. What can you conclude about the WHO limit of 11.3 mg/L?
Q2. Why use a t-distribution rather than a normal distribution for small samples?
Your Goal
GW-14's Year 5 data: n=365, mean=8.7 mg/L, s=2.1 mg/L. Using t_crit ≈ 1.967 for df=364, compute the 95% CI. Does the upper bound exceed the WHO limit of 11.3 mg/L?
Hint: SE = 2.1/√365. Margin = 1.967 × SE. CI = (8.7 − margin, 8.7 + margin).
Teach It Back
A colleague says 'our mean is 8.7, which is below 11.3, so we're safe.' Explain what's missing from this statement and how a confidence interval would improve it.