R ggplot2 - Add Labels, Title, Annotations
The `labs()` function provides the most straightforward approach to adding labels in ggplot2. It handles titles, subtitles, captions, and axis labels in a single function call.
Key Insights
- ggplot2 provides a layered system for adding text elements through
labs(),ggtitle(),xlab(),ylab(), andannotate()functions that work independently or together - Annotations differ from labels by placing text at specific coordinate positions, enabling detailed plot commentary using
annotate(),geom_text(), andgeom_label() - Advanced customization through
theme()allows precise control over text appearance, positioning, and styling for publication-ready visualizations
Basic Labels and Titles
The labs() function provides the most straightforward approach to adding labels in ggplot2. It handles titles, subtitles, captions, and axis labels in a single function call.
library(ggplot2)
# Create sample dataset
data <- data.frame(
x = 1:10,
y = rnorm(10, mean = 5, sd = 2),
category = rep(c("A", "B"), each = 5)
)
# Basic plot with comprehensive labels
ggplot(data, aes(x = x, y = y, color = category)) +
geom_point(size = 3) +
geom_line() +
labs(
title = "Performance Metrics Over Time",
subtitle = "Comparing Category A and B",
x = "Time Period",
y = "Performance Score",
color = "Category",
caption = "Source: Internal Analytics Database"
)
Individual label functions offer granular control when you need to add or modify specific elements:
ggplot(data, aes(x = x, y = y)) +
geom_point() +
ggtitle("Main Title", subtitle = "Additional Context") +
xlab("Independent Variable") +
ylab("Dependent Variable")
Mathematical Expressions in Labels
ggplot2 supports mathematical notation through R’s expression() function, essential for scientific and technical visualizations.
# Plot with mathematical expressions
ggplot(data.frame(x = seq(0, 10, 0.1)), aes(x = x)) +
stat_function(fun = function(x) x^2) +
labs(
title = expression(paste("Function: ", f(x) == x^2)),
x = expression(alpha + beta),
y = expression(sqrt(x + y))
)
# Greek letters and complex formulas
ggplot(data, aes(x = x, y = y)) +
geom_point() +
labs(
x = expression(mu[x] * " (mean)"),
y = expression(sigma^2 * " (variance)"),
title = expression(paste("Relationship between ", mu, " and ", sigma^2))
)
Point Annotations with geom_text and geom_label
Use geom_text() to add text labels directly on the plot area, typically to label specific data points.
# Label specific points
data$label <- ifelse(data$y > 6, paste0("Point ", data$x), "")
ggplot(data, aes(x = x, y = y)) +
geom_point(size = 3) +
geom_text(aes(label = label),
vjust = -0.5,
hjust = 0.5,
size = 3.5)
# Using geom_label for boxed text
ggplot(data, aes(x = x, y = y, color = category)) +
geom_point(size = 3) +
geom_label(aes(label = round(y, 1)),
vjust = -0.5,
size = 3,
label.padding = unit(0.15, "lines"))
The ggrepel package prevents label overlap automatically:
library(ggrepel)
# Create crowded data
crowded_data <- data.frame(
x = rnorm(50),
y = rnorm(50),
label = paste0("P", 1:50)
)
ggplot(crowded_data, aes(x = x, y = y, label = label)) +
geom_point() +
geom_text_repel(
size = 3,
max.overlaps = 20,
box.padding = 0.5,
point.padding = 0.3
)
Custom Annotations with annotate()
The annotate() function places text, shapes, or segments at specific coordinates without mapping to data.
# Text annotations at fixed positions
ggplot(data, aes(x = x, y = y)) +
geom_point() +
annotate("text",
x = 3,
y = 8,
label = "Peak Performance",
size = 4,
color = "red",
fontface = "bold") +
annotate("text",
x = 7,
y = 2,
label = "Low Point",
size = 4,
color = "blue")
# Rectangle annotation for highlighting regions
ggplot(data, aes(x = x, y = y)) +
geom_line() +
annotate("rect",
xmin = 4, xmax = 6,
ymin = -Inf, ymax = Inf,
alpha = 0.2,
fill = "yellow") +
annotate("text",
x = 5, y = 8,
label = "Critical Period",
fontface = "italic")
Arrow Annotations and Segments
Combine annotations with arrows to point out specific features:
# Arrow pointing to specific data point
max_point <- data[which.max(data$y), ]
ggplot(data, aes(x = x, y = y)) +
geom_line() +
geom_point() +
annotate("segment",
x = max_point$x + 1.5,
xend = max_point$x + 0.2,
y = max_point$y + 1,
yend = max_point$y + 0.1,
arrow = arrow(length = unit(0.3, "cm")),
color = "red",
size = 1) +
annotate("text",
x = max_point$x + 1.5,
y = max_point$y + 1.2,
label = sprintf("Maximum: %.2f", max_point$y),
hjust = 0,
color = "red")
Multi-line Annotations
For longer annotations, use \n for line breaks or the paste() function:
ggplot(data, aes(x = x, y = y)) +
geom_point() +
annotate("text",
x = 2,
y = 8,
label = "Multi-line annotation\nLine 2\nLine 3",
size = 3.5,
lineheight = 0.9,
hjust = 0) +
annotate("label",
x = 8,
y = 2,
label = paste("Boxed text", "with multiple lines", sep = "\n"),
size = 3)
Theme Customization for Text Elements
The theme() function provides extensive control over all text elements:
ggplot(data, aes(x = x, y = y, color = category)) +
geom_point(size = 3) +
labs(
title = "Customized Text Elements",
subtitle = "Complete theme control",
x = "X Axis",
y = "Y Axis"
) +
theme(
plot.title = element_text(
size = 16,
face = "bold",
hjust = 0.5,
color = "#2C3E50"
),
plot.subtitle = element_text(
size = 12,
hjust = 0.5,
color = "#7F8C8D",
margin = margin(b = 10)
),
axis.title.x = element_text(
size = 12,
face = "bold",
margin = margin(t = 10)
),
axis.title.y = element_text(
size = 12,
face = "bold",
margin = margin(r = 10)
),
axis.text = element_text(
size = 10,
color = "#34495E"
),
legend.title = element_text(
size = 11,
face = "bold"
),
legend.text = element_text(size = 10)
)
Dynamic Labels from Data
Generate labels programmatically based on data characteristics:
# Calculate statistics for labels
library(dplyr)
summary_stats <- data %>%
group_by(category) %>%
summarize(
mean_y = mean(y),
max_x = max(x)
)
ggplot(data, aes(x = x, y = y, color = category)) +
geom_point() +
geom_text(
data = summary_stats,
aes(x = max_x, y = mean_y,
label = sprintf("Mean: %.2f", mean_y)),
hjust = 1.1,
size = 3.5,
show.legend = FALSE
)
Facet Labels
Customize facet labels using labeller():
# Custom facet labels
data$facet_var <- rep(c("group_1", "group_2"), length.out = nrow(data))
ggplot(data, aes(x = x, y = y)) +
geom_point() +
facet_wrap(
~facet_var,
labeller = labeller(
facet_var = c(
"group_1" = "First Group",
"group_2" = "Second Group"
)
)
) +
theme(strip.text = element_text(size = 12, face = "bold"))
This comprehensive approach to labels and annotations transforms basic plots into informative visualizations. Combine these techniques based on your specific requirements—use labs() for standard labeling, annotate() for commentary, and theme() for precise styling control. The layered nature of ggplot2 allows incremental refinement until you achieve the exact presentation needed for your audience.