How to Plot a Histogram in R

· 2 min read · Updated March 14, 2026 · beginner
r histogram visualization ggplot2 base

Histograms display the distribution of a continuous variable by grouping data into bins. This cookbook shows multiple ways to create histograms in R.

With ggplot2

The ggplot2 package provides the most flexible approach:

library(ggplot2)

# Basic histogram
ggplot(mtcars, aes(x = mpg)) +
  geom_histogram()
# stat_bin using bins = 30. Pick better value with binwidth.

Set the number of bins:

ggplot(mtcars, aes(x = mpg)) +
  geom_histogram(bins = 10, fill = "steelblue", color = "white")

Set bin width instead:

ggplot(mtcars, aes(x = mpg)) +
  geom_histogram(binwidth = 2, fill = "coral", color = "black")

Add density curve overlay:

ggplot(mtcars, aes(x = mpg, y = after_stat(density))) +
  geom_histogram(bins = 10, fill = "lightgray", color = "black") +
  geom_density(color = "red", linewidth = 1)

With base R

Use the hist() function:

# Basic histogram
hist(mtcars$mpg)
# breaks
# [1] 10 15 20 25 30 35
# counts
# [1] 5 7 8 5 3 2

# Custom number of breaks
hist(mtcars$mpg, breaks = 10, col = "lightblue", border = "black")

# Add a title
hist(mtcars$mpg, main = "Miles Per Gallon Distribution", 
     xlab = "MPG", ylab = "Frequency")

With graphics package

The basic graphics package also supports histograms:

# Using hist() from graphics (same as base R)
hist(mtcars$mpg, probability = TRUE, 
     col = "wheat", border = "brown",
     main = "MPG Distribution", xlab = "Miles per Gallon")

# Add kernel density estimate
lines(density(mtcars$mpg), col = "red", lwd = 2)

Customizing Histograms

Color by group

library(ggplot2)

# Histogram colored by another variable
ggplot(mtcars, aes(x = mpg, fill = factor(cyl))) +
  geom_histogram(bins = 8, alpha = 0.7, position = "dodge")

Faceted histograms

ggplot(mtcars, aes(x = mpg)) +
  geom_histogram(bins = 8, fill = "steelblue") +
  facet_wrap(~ cyl, ncol = 1)

Custom bin boundaries

# Specify exact break points
ggplot(mtcars, aes(x = mpg)) +
  geom_histogram(breaks = c(10, 15, 20, 25, 30, 35),
                 fill = "mediumseagreen", color = "white")

See Also