📚 Math in Society
⇩ Download ▾

11.5 Measures of Variation

Consider these three sets of quiz scores:

import math

# Four quiz sections. Every one has mean 5 and median 5 -- only the SPREAD differs.
# CHANGE any list (or add "Section E") and re-run.
sections = {
    "Section A": [5, 5, 5, 5, 5, 5, 5, 5, 5, 5],
    "Section B": [0, 0, 0, 0, 0, 10, 10, 10, 10, 10],
    "Section C": [4, 4, 4, 5, 5, 5, 5, 6, 6, 6],
    "Section D": [0, 5, 5, 5, 5, 5, 5, 5, 5, 10],
}

def std_dev(data, is_population=True):
    """The book's five steps, written out."""
    mean = sum(data) / len(data)
    squared = [(x - mean) ** 2 for x in data]           # steps 1 and 2
    total = sum(squared)                                # step 3
    divisor = len(data) if is_population else len(data) - 1   # step 4
    return math.sqrt(total / divisor), mean, total, divisor   # step 5

print("%-11s %7s %7s %10s %10s" % ("section", "mean", "range", "pop sd", "sample sd"))
print("-" * 50)
for name, data in sections.items():
    pop, mean, _, _ = std_dev(data, True)
    smp, _, _, _    = std_dev(data, False)
    print("%-11s %7.1f %7d %10.2f %10.2f" % (name, mean, max(data) - min(data), pop, smp))
print("-" * 50)
print("Sections B and D have the SAME range (10) but very different spread.")
print("Range only looks at two data values; standard deviation looks at all of them.")
print()

# The full worked table for one section -- change which one:
SHOW = "Section D"      # <-- CHANGE ME
data = sections[SHOW]
sd, mean, total, divisor = std_dev(data, True)
print("%s, step by step (mean = %.1f):" % (SHOW, mean))
print("%12s %26s %18s" % ("data value", "deviation: value - mean", "deviation squared"))
for x in data:
    print("%12d %26s %18.2f" % (x, "%d - %.1f = %+.1f" % (x, mean, x - mean), (x - mean) ** 2))
print("%12s %26s %18.2f" % ("", "sum of squared deviations", total))
print("divide by n = %d  ->  variance %.2f   (points SQUARED -- so take the root)"
      % (divisor, total / divisor))
print("population standard deviation = sqrt(%.2f) = %.2f points" % (total / divisor, sd))

All three of these sets of data have a mean of 5 and median of 5, yet the sets of scores are clearly quite different. In section A, everyone had the same score; in section B half the class got no points and the other half got a perfect score, assuming this was a 10-point quiz. Section C was not as consistent as section A, but not as widely varied as section B.

In addition to the mean and median, which are measures of the "typical" or "middle" value, we also need a measure of how "spread out" or varied each data set is.

There are several ways to measure this "spread" of the data. The first is the simplest and is called the range.

In the last example, the range seems to be revealing how spread out the data is. However, suppose we add a fourth section, Section D, with scores 0 5 5 5 5 5 5 5 5 10.

This section also has a mean and median of 5. The range is 10, yet this data set is quite different than Section B. To better illuminate the differences, we’ll have to turn to more sophisticated measures of variation.

Using the data from section D, we could compute for each data value the difference between the data value and the mean:

data valuedeviation: data value - mean
00-5=-5
55-5=0
55-5=0
55-5=0
55-5=0
55-5=0
55-5=0
55-5=0
55-5=0
1010-5=5

We would like to get an idea of the "average" deviation from the mean, but if we find the average of the values in the second column the negative and positive values cancel each other out (this will always happen), so to prevent this we square every value in the second column:

We then add the squared deviations up to get 25+0+0+0+0+0+0+0+0+25=50. Ordinarily we would then divide by the number of scores, n, (in this case, 10) to find the mean of the deviations. But we only do this if the data set represents a population; if the data set represents a sample (as it almost always does), we instead divide by n1 (in this case, 101=9).[1]

So in our example, we would have 5010=5 if section D represents a population and 509= about 5.56 if section D represents a sample. These values (5 and 5.56) are called, respectively, the population variance and the sample variance for section D.

Variance can be a useful statistical concept, but note that the units of variance in this instance would be points-squared since we squared all of the deviations. What are points-squared? Good question. We would rather deal with the units we started with (points in this case), so to convert back we take the square root and get:

population standard deviation = 50 10 = 5 2.2

or

sample standard deviation = 50 9 2.4

If we are unsure whether the data set is a sample or a population, we will usually assume it is a sample, and we will round answers to one more decimal place than the original data, as we have done above.

For comparison, the standard deviations of all four sections are:

Section A: 5 5 5 5 5 5 5 5 5 5Standard deviation: 0
Section B: 0 0 0 0 0 10 10 10 10 10Standard deviation: 5
Section C: 4 4 4 5 5 5 5 6 6 6Standard deviation: 0.8
Section D: 0 5 5 5 5 5 5 5 5 10Standard deviation: 2.2

Where standard deviation is a measure of variation based on the mean, quartiles are based on the median.

While quartiles are not a 1-number summary of variation like standard deviation, the quartiles are used with the median, minimum, and maximum values to form a 5 number summary of the data.

To find the first quartile, we need to find the data value so that 25% of the data is below it. If n is the number of data values, we compute a locator by finding 25% of n. If this locator is a decimal value, we round up, and find the data value in that position. If the locator is a whole number, we find the mean of the data value in that position and the next data value. This is identical to the process we used to find the median, except we use 25% of the data values rather than half the data values as the locator.

Examples should help make this clearer.

Note that the median could be computed the same way, using 50%.

The 5-number summary combines the first and third quartile with the minimum, median, and maximum values.

Of course, with a relatively small data set, finding a five-number summary is a bit silly, since the summary contains almost as many values as the original data.

Note that the 5 number summary divides the data into four intervals, each of which will contain about 25% of the data. In the previous example, that means about 25% of households have income between $40 thousand and $50 thousand.

For visualizing data, there is a graphical representation of a 5-number summary called a box plot, or box and whisker graph.

To create a box plot, a number line is first drawn. A box is drawn from the first quartile to the third quartile, and a line is drawn through the box at the median. “Whiskers” are extended out to the minimum and maximum values.

Box plots are particularly useful for comparing data from two populations.

import math
import matplotlib.pyplot as plt

def locate(sorted_data, fraction):
    """The book's locator rule: L = fraction * n; round up, or average two values."""
    n = len(sorted_data)
    L = fraction * n
    if L == int(L):                       # whole number -> mean of the Lth and (L+1)th
        L = int(L)
        return (sorted_data[L - 1] + sorted_data[L]) / 2
    return sorted_data[math.ceil(L) - 1]  # decimal -> round up, take that value

def five_number(data):
    s = sorted(data)
    return [s[0], locate(s, 0.25), locate(s, 0.50), locate(s, 0.75), s[-1]]

# Book data sets. CHANGE any list, or paste your own, and re-run.
sets = {
    "9 female heights (in)": [59, 60, 62, 64, 66, 67, 69, 70, 72],
    "8 female heights (in)": [59, 60, 62, 64, 66, 67, 69, 70],
    "36 textbook costs ($)": [140, 160, 160, 165, 180, 220, 235, 240, 250, 260, 280,
                              285, 285, 285, 290, 300, 300, 305, 310, 310, 315, 315,
                              320, 320, 330, 340, 345, 350, 355, 360, 360, 380, 395,
                              420, 460, 460],
}

print("%-24s %8s %8s %8s %8s %8s %9s" % ("data set", "min", "Q1", "median", "Q3", "max", "IQR"))
print("-" * 76)
for name, data in sets.items():
    mn, q1, med, q3, mx = five_number(data)
    print("%-24s %8.2f %8.2f %8.2f %8.2f %8.2f %9.2f" % (name, mn, q1, med, q3, mx, q3 - q1))
print("-" * 76)
print("Each of the four pieces holds about 25% of the data -- so a WIDE box means")
print("the middle half of the data is spread out, not that there are more values in it.")

# Boxplot of the two height samples, drawn straight from the book's five-number summary.
fig, ax = plt.subplots(figsize=(6, 3.4))
stats = []
for name in ("9 female heights (in)", "8 female heights (in)"):
    mn, q1, med, q3, mx = five_number(sets[name])
    stats.append({"label": name, "med": med, "q1": q1, "q3": q3,
                  "whislo": mn, "whishi": mx, "fliers": []})
ax.bxp(stats, showfliers=False, patch_artist=True,
       boxprops={"facecolor": "#dbe5f1"}, medianprops={"color": "#c00000"})
ax.set_ylabel("height (inches)")
ax.set_title("Five-number summaries as box plots")
plt.tight_layout()
plt.show()

[1] The reason we do this is highly technical, but we can see how it might be useful by considering the case of a small sample from a population that contains an outlier, which would increase the average deviation: the outlier very likely won't be included in the sample, so the mean deviation of the sample would underestimate the mean deviation of the population; thus we divide by a slightly smaller number to get a slightly bigger average deviation.

[2] van Vliet, P.K. and Gupta, J.M. (1973) Sodium bicarbonate in idiopathic respiratory distress syndrome. Arch. Disease in Childhood, 48, 249–255. As quoted on http://openlearn.open.ac.uk/mod/ouco...&section=1.1.3

Adapted from Math in Society by David Lippman, hosted on LibreTexts (math.libretexts.org) and licensed under CC BY-SA 3.0. Changes were made. License: CC-BY-SA-3.0.

These eBooks are a prerelease and are not yet certified conformant with WCAG 2.1 AA or ADA Title II. Every page is built against an automated accessibility gate, and the published editions will meet ADA Title II requirements when they release in late September 2026. If something is unusable, please tell us.