Skip to content

R - Boxplots

Boxplots (or box-and-whisker plots) are a powerful way to visualize the distribution of a continuous variable. They concisely display key statistical measures: the minimum, first quartile (Q1), median (Q2), third quartile (Q3), and maximum. They are especially useful for comparing the distributions of a variable across different categories.

Today, ggplot2 is the standard for creating flexible and publication-quality boxplots in R.

A boxplot shows:

  • The median: The line inside the box.
  • The interquartile range (IQR): The box itself, stretching from the 25th percentile (Q1) to the 75th percentile (Q3).
  • The whiskers: Lines extending from the box to show the range of the data. Typically, they extend to 1.5 times the IQR from the box edges.
  • Outliers: Points that fall beyond the whiskers.

We’ll use the mtcars dataset to compare the distribution of mpg (Miles Per Gallon) across cars with different numbers of cyl (Cylinders).

# We will use ggplot2 from the tidyverse
# install.packages("tidyverse")
library(ggplot2)
library(dplyr)
# It's good practice to treat the categorical variable as a factor
# This ensures ggplot2 handles it correctly.
input_data <- mtcars %>%
mutate(cyl = factor(cyl))
print(head(input_data[, c('mpg', 'cyl')]))

When we execute the above code, it produces the following result:

mpg cyl
Mazda RX4 21.0 6
Mazda RX4 Wag 21.0 6
Datsun 710 22.8 4
Hornet 4 Drive 21.4 6
Hornet Sportabout 18.7 8
Valiant 18.1 6

We build the plot by specifying the categorical variable (cyl) on the x-axis and the continuous variable (mpg) on the y-axis, then adding the geom_boxplot layer.

# Create the boxplot
boxplot_cyl <- ggplot(data = input_data, aes(x = cyl, y = mpg)) +
geom_boxplot() +
labs(
title = "Distribution of Fuel Efficiency by Number of Cylinders",
x = "Number of Cylinders",
y = "Miles Per Gallon (MPG)"
) +
theme_classic()
# Display the plot
print(boxplot_cyl)
# Save the plot to a file
ggsave("boxplot.png", width = 7, height = 5)

This code generates a clear boxplot, boxplot.png, showing that as the number of cylinders increases, the median miles per gallon decreases and its distribution changes.

We can easily customize the appearance and add more information. Notches can be added to give a rough guide to the significance of the difference between medians; if the notches of two boxes do not overlap, it’s strong evidence their medians differ. We can also map a variable (or set a fixed color) to the fill aesthetic.

# Create a customized boxplot with notches and colors
boxplot_custom <- ggplot(data = input_data, aes(x = cyl, y = mpg, fill = cyl)) +
geom_boxplot(
notch = TRUE, # Add notches to the boxes
outlier.color = "red", # Customize the color of outlier points
outlier.shape = 4
) +
stat_summary(fun = mean, geom = "point", shape = 18, size = 3, color = "white") + # Add mean points
labs(
title = "Mileage Data Comparison",
subtitle = "Notches indicate median confidence intervals. White diamonds are means.",
x = "Number of Cylinders",
y = "Miles Per Gallon (MPG)"
) +
scale_fill_brewer(palette = "Pastel1") + # Use a color palette
theme_gray() +
guides(fill = "none") # Hide the redundant legend for fill color
# Display the plot
print(boxplot_custom)
# Save the plot to a file
ggsave("boxplot_with_notch.png", width = 8, height = 6)

This advanced example demonstrates several ggplot2 features:

  • notch = TRUE adds the confidence interval notches.
  • Aesthetics like fill are mapped within aes() for data-driven coloring.
  • stat_summary() adds an extra layer showing the mean, which can differ from the median.
  • scale_fill_brewer() applies a pre-defined, aesthetically pleasing color palette.