Histogram
ggplot2: geom_histogram() · Package: ggplot2 · Variables: 1 numerical
WHAT IS A HISTOGRAM?
A histogram groups a continuous variable into equal-width bins and shows the frequency (count) in each bin as a bar. It reveals the distribution shape — is it symmetric, skewed left or right, bimodal, or uniform? Histograms answer "how is my data distributed?" and are essential for understanding spread, central tendency, and outliers before any deeper analysis. The number of bins matters: too few bins hide patterns, too many create noise. A common rule of thumb is the square root of n. In ggplot2, use geom_histogram() and adjust the bins or binwidth parameter.
HOW TO READ A HISTOGRAM
A histogram shows where observations concentrate along a continuous scale. Read it for four things: centre, spread, shape and outliers. A long tail to the right — typical of income, revenue and duration data — means the mean sits above the median and summary statistics will mislead if you quote only the average. Two distinct peaks usually mean two populations are mixed in one dataset, which is often the most valuable thing a histogram can tell you. Gaps and isolated bars at the extremes deserve investigation before analysis proceeds. Bin width is not a cosmetic choice: it is a parameter of the estimate. Wide bins smooth real structure away, narrow ones turn sampling noise into apparent peaks, and the honest approach is to try several and report a shape that persists across them.
BEST FOR
- · Understanding distribution shape
- · Identifying skewness
- · Finding outliers
- · Assessing spread
AVOID WHEN
- · Categorical data
- · Very small samples (under 20)
- · Comparing many groups simultaneously
R + GGPLOT2 CODE EXAMPLE
ggplot(mtcars, aes(x = mpg)) + geom_histogram(bins = 12, fill = "#ff6a00", color = "white") + labs(title = "Distribution of MPG", x = "MPG", y = "Count")
HISTOGRAM WITH DENSITY OVERLAY AND A MEDIAN MARKER
Counts converted to density so a smoothed curve can be overlaid on the same scale, with the median marked — enough to judge skew at a glance.
library(ggplot2)
ggplot(mtcars, aes(x = mpg)) +
geom_histogram(
aes(y = after_stat(density)),
binwidth = 2, fill = "#ff6a00", colour = "white", alpha = 0.85
) +
geom_density(colour = "#1c1c17", linewidth = 0.7) +
geom_vline(
xintercept = median(mtcars$mpg),
linetype = "dashed", colour = "#1c1c17"
) +
annotate("text", x = median(mtcars$mpg) + 0.6, y = 0.075,
label = "median", hjust = 0, size = 3.5) +
labs(title = "Distribution of fuel economy",
subtitle = "Bin width 2 mpg, density scale",
x = "Miles per gallon", y = "Density") +
theme_minimal(base_size = 12)
# Compare several bin widths before settling on one:
# ggplot(mtcars, aes(mpg)) + geom_histogram(binwidth = 1)
# ggplot(mtcars, aes(mpg)) + geom_histogram(binwidth = 5)COMMON MISTAKES WITH THIS CHART
Accepting the default 30 bins
ggplot2 warns about this for good reason. Set binwidth in the units of your variable — binwidth = 5 for ages, binwidth = 1000 for salaries — so the bins mean something to the reader.
Confusing a histogram with a bar chart
Histogram bars touch because the x-axis is continuous and the bins are adjacent intervals. Bar charts have gaps because the categories are discrete. Using one for the other misrepresents the variable type.
Overlaying several groups on one histogram
Overlapping fills obscure each other whatever the alpha. Use facet_wrap(~group) for separate panels, or geom_density() where outlines can overlap legibly.
Reading a single peak as proof of normality
Unimodal is not the same as normal. Confirm with a Q-Q plot before relying on any method that assumes normality.
Run this code now
Paste the code above into RChat and see the histogram rendered instantly in your browser.