Blinded by the Mean: Why Averages Hide the Real Story
Averages are a staple of business reporting. They're simple to calculate, easy to put in a slide, and seem to offer a definitive answer to comparisons between teams, products, or time periods. But using a single number to summarize a group of numbers often obscures more than it reveals. The shape of the data behind that average — its distribution — is where the real insight lives.
Consider a common scenario: you need to decide which of your sales leaders deserves a major reward. Revenue is the only metric that matters in this company, and the decision hinges on who drove the most growth this year. The headline numbers seem to make the case.
| name | average revenue increase (%) |
|---|---|
| alice | 5.0 |
| bob | 7.9 |
| clara | 5.0 |
A colorful bar chart makes it obvious: Bob, with revenue up just under 8%, is the clear winner. His rivals Alice and Clara are stuck at around 5% growth for the year. The decision looks straightforward.
But then you look at the underlying performance on individual accounts.
| name | account revenue increases (%) | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| alice | -1.0 | 2.0 | 1.0 | -3.0 | -1.0 | 10.0 | 13.0 | 8.0 | 11.0 | 10.0 |
| bob | -0.5 | -2.5 | -6.0 | -1.5 | -2.0 | -1.8 | -2.3 | 80.0 | ||
| clara | 3.0 | 7.0 | 4.5 | 5.5 | 4.8 | 5.0 | 5.2 | 4.0 | 6.0 | 5.0 |
The account-level view tells a much more nuanced story. Bob's average is inflated by a single account that grew by 80%. Every other account he manages shrank. Is a person whose performance rests on one big win really the best candidate for a bonus? Meanwhile, Alice and Clara may have identical averages, but their paths to that number differ enormously. Alice splits sharply between very strong performers and mediocre ones, while Clara is a consistent, if moderate, grower across the board.
This is a textbook example of the mean's weakness: it is highly sensitive to a single outlier. You can have a hundred homeless people in a room and one billionaire, and the "average" net worth of the group is $10 million — a number that describes no one in the room.
None of this is new to a statistician, but in corporate life, the practice of comparing only averages remains stubbornly widespread. Bars showing means dominate boardroom decks, and the discussions they prompt often miss the point entirely. What's needed is a habit of looking at the distribution itself before making up your mind.
Seeing Every Point: The Strip Chart
The first step to escaping the tyranny of averages is simply plotting every individual data point. For a small group of numbers — say a dozen or fewer — a strip chart is ideal. It puts every account's revenue change on the axis so you can literally see what's happening. A few lines of R code will generate one.
show code
ggplot(sales, aes(name, d_revenue, color=name)) + geom_jitter(width=0.15, alpha = 0.4, size=5, show.legend=FALSE) + ylab(label = "revenue increase (%)") + geom_hline(yintercept = 0) + theme_grey(base_size=30)
With Bob's data plotted this way, it's immediately obvious that his strong overall average is almost entirely due to one high-flying account. His other accounts look similar to Alice's worst, and Clara's results form a tight, consistent cluster. For someone making a hiring or promotion decision, this is the information that matters most, and a strip chart surfaces it in seconds.
This kind of plot is easy to create with freely available software. Excel exists in most offices, but strip charts are rarely seen in PowerPoint decks built from spreadsheets. The open-source R programming language is a popular tool among data analysts. It offers robust plotting features without licensing costs, and has extensive tutorials for newcomers who want to tweak graphs rather than learn applied mathematics. Each chart in this discussion can be reproduced by code provided in the disclosure panels below them. (Pythonistas have a fine range of libraries for the same tasks, too.)
The need to see distributions becomes even more pressing as datasets scale. If our trio now manages a couple of hundred accounts each, a strip chart remains a powerful way to compare them.
show code
ggplot(large_sales, aes(name, value, color=name)) + geom_jitter(width=0.15, alpha = 0.4, size=2, show.legend=FALSE) + ylab(label = "revenue increase (%)") + geom_hline(yintercept = 0) + theme_grey(base_size=30)
At this sample size, the visual pattern confirms what we already suspected: Alice has two blocks of performance, Clara is consistently average, and Bob trails behind on most of his accounts.
Many people worry about losing sight of the average when using a strip chart. It's true that a centralized number is still valuable; the problem is only when it's the sole point of comparison. Adding a marker for the mean — shown as a dark diamond here — puts it back in context.
show code
ggplot(large_sales, aes(name, value, color=name)) + geom_jitter(width=0.15, alpha = 0.4, size=2, show.legend=FALSE) + ylab(label = "revenue increase (%)") + geom_hline(yintercept = 0) + stat_summary(fun = "mean", size = 5, geom = "point", shape=18, color = 'black') + theme_grey(base_size=30)
With this addition, we see that Bob's mean is actually slightly lower than the others once his outlier is balanced against the rest. Averages aren't useless — I just find fault with the habit of using them in isolation. When you do use a single measure of central tendency, consider that the median may represent your group's "typical" case far better than the mean does, since it holds up better to outliers.
Medians are underused not because they lack value, but because the tools make it awkward. SQL, the standard language for querying data, has a built-in AVG function for the mean. Calculating a median often sends users on a fruitless search for long-forgotten algorithms, unless they can install extensions to their database. A good design rule: no platform should offer a mean function without a median.
Seeing Shapes: Histograms and Density Plots
When a group has more data points, other visualization techniques become useful for revealing the shape of its distribution. Histograms give a clear, intuitive view of a single group's shape, dividing values into buckets and counting their frequencies. For the larger simulated dataset, the story is easy to read.
show code
ggplot(large_sales, aes(value, fill=name)) + geom_histogram(binwidth = 1, boundary=0, show.legend=FALSE) + xlab(label = "revenue increase (%)") + scale_y_continuous(breaks = c(50,100)) + geom_vline(xintercept = 0) + theme_grey(base_size=30) + facet_wrap(~ name,ncol=1)
These charts show clearly that Alice's deals fall into two distinct clusters, while Clara's performance forms a single, narrow peak. For making comparisons, R offers a special feature known as faceted plots — variations of "small multiples," to use Tufte's term — which present histograms for each group side by side. This can be a powerful tool for analysis and communication.
Density plots are another option, functioning much like a smoothed-out histogram.
show code
ggplot(large_sales, aes(value, color=name)) + geom_density(show.legend=FALSE) + geom_vline(xintercept = 0) + xlab(label = "revenue increase (%)") + scale_y_continuous(breaks = c(0.1)) + theme_grey(base_size=30) + facet_wrap(~ name,ncol=1)
The vertical axis on a density plot isn't highly meaningful to me, so the chart is often best with that scale removed — the point is the distribution's shape. Because density plots render as smooth lines, they allow the most compact comparison: all the groups on a single chart.
show code
ggplot(large_sales, aes(value, color=name)) + geom_density(size=2) + scale_y_continuous(breaks = NULL) + xlab(label = "revenue increase (%)") + geom_vline(xintercept = 0) + theme_grey(base_size=30)
That graph by itself makes the case: Alice is bimodal — either successful or mediocre, Clara is consistently around 5%, and Bob trails badly except for the single spike at 80%.
Histograms and density plots work well when datasets have many values. For a handful of points, a bar chart of counts can serve a similar purpose. Consider a site that lets users rate products with one to five stars: alongside the average score, showing how many times each rating was given is far more informative. Amazon caught on to this long ago, adding that distribution break-down to its reviews — a reminder that the basic lesson of looking beyond averages is valuable everywhere.
Beyond Histograms: Comparing Many Distributions
Histograms and density plots are excellent for examining the shape of a single distribution. But when you need to compare a dozen or more groups, those chart types become unwieldy. It also helps to see commonly defined ranges within the data. That is where the boxplot becomes the right tool.
show code
ggplot(large_sales, aes(name, value, color=name)) + geom_boxplot(show.legend=FALSE) + ylab(label = "revenue increase (%)") + geom_hline(yintercept = 0) + theme_grey(base_size=30)
The boxplot focuses attention on the middle range of data, where half of the data points sit within the box. In the sales example, this view makes it immediately clear that more than half of Bob's accounts shrank, and that his upper quartile sits below Clara's lower quartile. His small cluster of hot accounts at the upper end remains visible.
Boxplots scale well to a couple of dozen comparisons. Consider daily high temperatures in London and Boston since 1983, summarized by month. This chart condenses over 27,000 data points.
show code
ggplot(temps, aes(month, high_temp, color=factor(city))) + ylab(label = "daily high temp (°C)") + theme_grey(base_size=20) + scale_x_discrete(labels=month.abb) + labs(color = NULL) + theme(legend.position = "bottom") + geom_boxplot()
The chart reveals that London's median winter temperatures are warmer, while its summers are cooler. It also shows how monthly variation differs. Over a quarter of the time, Boston's January high never exceeds freezing, and Boston's upper quartile barely reaches London's lower quartile. Still, there are occasions where a January day in Boston is warmer than any January day London ever sees.
The boxplot's weakness is that it hides the exact shape of the data. For instance, the double-peak in Alice's distribution is invisible in a boxplot in a way it would not be in a histogram. There are two common workarounds. The first is to overlay the boxplot with a strip chart showing the underlying data points, along with a marker for the mean.
show code
ggplot(large_sales, aes(name, value, color=name)) + geom_boxplot(show.legend=FALSE, outlier.shape = NA) + geom_jitter(width=0.15, alpha = 0.4, size=1, show.legend=FALSE) + ylab(label = "revenue increase (%)") + stat_summary(fun = "mean", size = 5, geom = "point", shape=18, color = 'black') + geom_hline(yintercept = 0) + theme_grey(base_size=30)
Adding the diamond marker helps flag cases like Bob's where the mean and median diverge substantially. The second approach is the violin plot, which draws a density plot on either side of the box area.
show code
ggplot(large_sales, aes(name, value, color=name, fill=name)) + geom_violin(show.legend=FALSE, alpha = 0.5) + ylab(label = "revenue increase (%)") + geom_hline(yintercept = 0) + theme_grey(base_size=30)
Violin plots make distribution shape explicit, so Alice's double peak stands out clearly. They are most effective with a larger number of points. For the small sales dataset, plotting individual points inside the box is more informative, but with tens of thousands of temperature measurements, the trade-off shifts.
show code
ggplot(temps, aes(month, high_temp, fill=factor(city))) + ylab(label = "daily high temp (°C)") + theme_grey(base_size=20) + labs(fill = NULL) + scale_x_discrete(labels=month.abb) + theme(legend.position = "bottom") + geom_violin(color = NA)
With weather data, the violins communicate the shape for each month, yet the box chart remains easier to compare across months. Aggregate signposts like medians and quartiles make for quicker visual comparisons. Exploring data benefits from trying several plot types to discover which aspects matter most before settling on the final visualization.
Key Takeaways
- Do not compare groups using only an average unless you understand the shape of the underlying data.
- When someone shows you summary statistics alone, ask what the distribution looks like.
- Use several plot types when exploring how groups differ.
- Consider whether a mean or median is the more appropriate summary for the question at hand.
- Choose charts—sometimes more than one—that highlight the essential features of your data.
- Above all, plot the distribution.
A Personal Note on Tools
The author of the original analysis first learned R about 15 years ago and was initially put off by the manual calculation involved in statistics. R appealed because it supported charts rarely available elsewhere, even though the language itself felt risky to navigate. Recent work by Hadley Wickham and the tidyverse ecosystem has made R far more approachable. All the visualizations discussed here use the ggplot2 library. The dplyr library enables chaining operations on tabular data in a collection-pipeline style, extended with table-specific operations such as joins and pivots.
The book R for Data Science by Wickham and Garrett Grolemund serves as both a data analytics tutorial and a frequent reference. The community-built R Studio environment provides a solid editor, though some still prefer Emacs. R as a programming language remains quirky, but for statistical data work, the tidyverse has proven an excellent choice.



