ggplot2 labs() in R: Title, Subtitle, Caption and Axes
The labs() function in ggplot2 sets every text label on a plot, title, subtitle, caption, tag, axis names, and legend titles, in a single call. It is the modern replacement for ggtitle(), xlab() and ylab().
labs(title = "Main title") # plot title labs(subtitle = "Below title") # subtitle line labs(caption = "Source: mtcars") # bottom-right caption labs(x = "Weight (1000 lbs)", y = "MPG") # axis labels labs(tag = "Fig. 1") # top-left tag labs(color = "Cylinders") # legend title labs(alt = "Scatter of mpg vs weight") # accessibility alt text
Need explanation? Read on for examples and pitfalls.
What labs() does in one sentence
labs() is the one function for every plot label in ggplot2. It accepts arguments for title, subtitle, caption, tag, axis names, alt text, and any aesthetic that drives a legend (color, fill, size, shape, linetype). Passing NULL to any argument removes that label.
Syntax
labs(title = NULL, subtitle = NULL, caption = NULL, tag = NULL, alt = NULL, x = NULL, y = NULL, ...). The ... slot accepts any aesthetic name to override its legend title.
Six common patterns
1. Title only
2. Title plus subtitle
3. Axis labels with units
4. Caption for the data source
5. Override a legend title
6. Remove a default label
labs(...) must match the aesthetic names in aes(...). If you map aes(color = cyl), the legend title is set by labs(color = "..."). Mismatch the name and ggplot2 silently keeps the default.labs() vs ggtitle() vs xlab() vs ylab()
labs() consolidates four older helpers into one call. Each shortcut still works, but every label lives in one place when you use labs().
| Function | Sets | When to use |
|---|---|---|
labs() |
All labels at once | Default; one place to edit every text element |
ggtitle() |
Title (and optional subtitle) | Quick one-off title |
xlab() |
X axis only | Single-axis tweak |
ylab() |
Y axis only | Single-axis tweak |
Mixing them works (each writes its own slot), but a single labs() call is easier to maintain than four scattered calls. The official ggplot2 reference at ggplot2.tidyverse.org/reference/labs.html treats the shorter forms as wrappers around labs().
labs(title = "...", x = "...", y = "...") replaces the main, xlab, and ylab arguments of plot() and the xlab/ylab/main arguments of hist().Common pitfalls
Pitfall 1: wrong aesthetic name. aes(colour = cyl) (British spelling) needs labs(colour = "..."), not labs(color = "..."). ggplot2 accepts both spellings in aes(), but labs() argument names must match the spelling you used.
Pitfall 2: titles overflow narrow plots. A long title gets clipped when the plot is exported small. Add \n for a manual line break, or use theme(plot.title = element_text(size = 12)) to shrink it.
Pitfall 3: alt is invisible in standalone plots. The alt argument is read by screen readers when the plot is embedded in a Quarto, R Markdown, or Shiny output. It does not display visually. Set it anyway for accessibility.
labs(title = "") is not the same as labs(title = NULL). An empty string keeps the title slot and leaves a blank gap above the plot. NULL removes the slot entirely.Try it yourself
Try it: Plot wt vs mpg from mtcars, colored by factor(cyl). Add a takeaway-style title, a subtitle naming the dataset, units on both axes, and rename the legend to "Cylinders". Save the plot to ex_plot.
Click to reveal solution
Explanation: One labs() call sets all five text slots. The legend title matches the color aesthetic in aes().
Related ggplot2 functions
After mastering labs(), look at:
ggtitle(): title-only shortcutxlab(),ylab(): single-axis shortcutstheme(): control font size, color, and position of every labelscale_x_continuous(labels = ...): format axis tick labelsannotate(): add text inside the plot panel
FAQ
What does labs() do in ggplot2?
labs() sets the title, subtitle, caption, tag, axis labels, alt text, and any legend title in a single call. It is the unified labels function, replacing the older ggtitle(), xlab(), and ylab() shortcuts. You can override any single slot or remove it by passing NULL.
What is the difference between labs() and ggtitle()?
ggtitle() only sets the title (and optionally the subtitle). labs() sets every label on the plot. If you only need a title, both work; if you need multiple labels, labs() keeps them in one place. The ggplot2 source defines ggtitle() as a thin wrapper around labs().
How do I add a subtitle in ggplot2?
Pass subtitle = "..." to labs(). The subtitle renders below the title in a slightly smaller, lighter font. To style it further, add theme(plot.subtitle = element_text(face = "italic")).
How do I change the legend title?
The legend title is controlled by the aesthetic name. If you mapped aes(color = group), write labs(color = "Group"). The argument name must match the aesthetic (color, fill, size, shape, linetype, alpha).
How do I remove the x axis label?
Pass NULL: labs(x = NULL). Passing an empty string (x = "") leaves an empty slot that still consumes vertical space.
Can I set alt text for accessibility?
Yes. Pass alt = "...". The alt text is read by screen readers when the plot is embedded in HTML output from Quarto, R Markdown, or Shiny. It does not show on the plot itself.