R Graphics · Histogram

Understanding Frequency Distributions with Histograms in R

Explore bin selection, density scaling, group comparison, reference curves, and ggplot2 styling.

6 examplesReproducible R code
Before you begin

Choose the variation that serves the analysis

Histograms divide a continuous scale into intervals. Their appearance depends on bin width, so responsible interpretation requires trying meaningful alternatives rather than accepting a default blindly.

Examples
06
Levels
Beginner + Intermediate
01
Example 01Base RBeginner

Build a Basic Histogram

A histogram counts observations within adjacent numeric intervals.

Build a Basic Histogram example generated in R
R-generated example output.

hist() chooses reasonable breaks automatically, while col and border improve visual separation.

RRun this code
hist(faithful$waiting, col = "#2563eb", border = "white",
     main = "Waiting times", xlab = "Minutes")
02
Example 02Base RBeginner

Control the Number of Bins

Changing the bins changes how much detail the histogram reveals.

Control the Number of Bins example generated in R
R-generated example output.

Too few bins hide structure; too many emphasize random variation. Compare several defensible choices.

RRun this code
hist(faithful$waiting, breaks = 20, col = "#60a5fa",
     border = "white", main = "Twenty bins", xlab = "Minutes")
03
Example 03Base RBeginner

Scale the Histogram to Density

Density scaling makes the total bar area equal to one.

Scale the Histogram to Density example generated in R
R-generated example output.

Set probability = TRUE when comparing the histogram with a probability-density curve.

RRun this code
x <- faithful$waiting
hist(x, probability = TRUE, col = "#bfdbfe", border = "white")
lines(density(x), col = "#dc2626", lwd = 3)
04
Example 04Base RIntermediate

Compare Two Histograms

Transparent overlapping histograms compare two distributions on common bins.

Compare Two Histograms example generated in R
R-generated example output.

Use identical breaks and transparency. For substantial overlap, separate panels or density curves may be clearer.

RRun this code
a <- iris$Sepal.Length[iris$Species == "setosa"]
b <- iris$Sepal.Length[iris$Species == "versicolor"]
breaks <- seq(4, 7.2, .3)
hist(a, breaks, col = adjustcolor("#2563eb", .5), xlim = c(4, 7.2))
hist(b, breaks, col = adjustcolor("#f59e0b", .5), add = TRUE)
05
Example 05Base RIntermediate

Display a Cumulative Histogram

A cumulative histogram shows how many observations fall at or below each boundary.

Display a Cumulative Histogram example generated in R
R-generated example output.

Calculate histogram counts without plotting, accumulate them with cumsum(), then draw the resulting bars.

RRun this code
h <- hist(faithful$waiting, plot = FALSE)
h$counts <- cumsum(h$counts)
plot(h, col = "#2563eb", border = "white",
     main = "Cumulative frequency", ylab = "Cumulative count")
06
Example 06ggplot2Intermediate

Create a Histogram with ggplot2

ggplot2 separates binning, aesthetics, labels, and themes into reusable layers.

Create a Histogram with ggplot2 example generated in R
R-generated example output.

Specify binwidth explicitly so the analytical choice is visible and reproducible.

RRun this code
library(ggplot2)
ggplot(faithful, aes(waiting)) +
  geom_histogram(binwidth = 5, fill = "#2563eb", color = "white") +
  labs(title = "Waiting-time distribution", x = "Minutes", y = "Count") +
  theme_minimal()