Change Axis Labels in R: A ggplot2 Guide

Rename, rotate, and remove x and y axis titles with labs() and theme()

Data Visualization

Learn to change ggplot2 axis labels in R — set the x and y axis titles with labs(), rotate tick text, remove a label, and restyle it with theme().

Published

July 8, 2026

Modified

July 9, 2026

TipKey takeaways
  • The axis label (or axis title) is the text naming an axis — set both at once with labs(x =, y =).
  • labs() is the modern one-stop function; the older xlab() / ylab() still work and do the same job.
  • Restyle a title’s colour, size, and font face with theme(axis.title.x = element_text(...)).
  • Rotate or realign a title with angle =, hjust, and vjust inside element_text().
  • Remove an axis title with labs(x = NULL) or theme(axis.title.x = element_blank()).
  • Every plot below is rendered for you — then tweak any example live in the sandbox.
Get the book — GGPlot2 Essentials (PDF)

Introduction

Axis labels are the titles that name each axis — “Dose (mg/day)” under the x-axis, “Tooth length” beside the y-axis. Good labels are the difference between a chart a reader understands at a glance and one they have to decode. In ggplot2 you control them with a single function, labs(), and fine-tune their look with theme().

This lesson covers every common task: setting the x and y titles, changing just one, restyling a title’s size/colour/face, rotating or realigning it, and removing it entirely. Each figure is rendered right here — re-run or edit any of them live.

Build the example plot

Every section starts from this box plot: dose (wrapped in factor()) on the x-axis and len on the y-axis, drawn from the built-in ToothGrowth data. Notice that ggplot2’s default axis titles are just the variable names — factor(dose) and len — which is exactly what we want to improve.

library(ggplot2)
ggplot(ToothGrowth, aes(x = factor(dose), y = len)) +
  geom_boxplot(fill = "#3a86d4", alpha = 0.7) +
  theme_minimal()

ggplot2 box plot of tooth length by vitamin C dose, showing the default axis titles factor(dose) and len.

Set the x and y axis labels

The one function to remember is labs(): pass x = and y = to rename both axes at once. This is the modern, preferred way — clearer than juggling two separate functions.

library(ggplot2)
ggplot(ToothGrowth, aes(x = factor(dose), y = len)) +
  geom_boxplot(fill = "#3a86d4", alpha = 0.7) +
  labs(x = "Dose (mg/day)", y = "Tooth length") +
  theme_minimal()

ggplot2 box plot with the x-axis titled Dose (mg per day) and the y-axis titled Tooth length via labs().

labs() also sets the plot title, subtitle, and caption from the same call, so you rarely need anything else for text.

Change only one axis label

To rename just one axis, pass only that argument to labs() — the other keeps its default. Here we retitle the y-axis and leave the x-axis untouched.

library(ggplot2)
ggplot(ToothGrowth, aes(x = factor(dose), y = len)) +
  geom_boxplot(fill = "#3a86d4", alpha = 0.7) +
  labs(y = "Odontoblast length (microns)") +
  theme_minimal()

ggplot2 box plot with only the y-axis renamed to Odontoblast length (microns), the x-axis left at its default.

The older xlab() and ylab()

You will still see xlab() and ylab() in older code and tutorials. They are single-purpose helpers that do exactly what the matching labs() argument does — xlab("...") equals labs(x = "..."). Both produce the same plot, so prefer labs() for one tidy call and treat these as equivalents you can read.

library(ggplot2)
ggplot(ToothGrowth, aes(x = factor(dose), y = len)) +
  geom_boxplot(fill = "#3a86d4", alpha = 0.7) +
  xlab("Dose (mg/day)") +
  ylab("Tooth length") +
  theme_minimal()

ggplot2 box plot with axis titles set through the older xlab() and ylab() helper functions.

Style the labels: size, colour, and font face

The look of a title lives in theme(), not labs(). Style the x title with axis.title.x and the y title with axis.title.y, each drawn by element_text(). Set colour, size, and face ("plain", "bold", "italic", or "bold.italic").

library(ggplot2)
ggplot(ToothGrowth, aes(x = factor(dose), y = len)) +
  geom_boxplot(fill = "#3a86d4", alpha = 0.7) +
  labs(x = "Dose (mg/day)", y = "Tooth length") +
  theme_minimal() +
  theme(
    axis.title.x = element_text(colour = "#3a86d4", size = 14, face = "bold"),
    axis.title.y = element_text(colour = "#993333", size = 14, face = "bold")
  )

ggplot2 box plot with a bold blue x-axis title and a bold dark-red y-axis title.

To style both titles the same way in one line, set axis.title instead of the two per-axis elements — for example theme(axis.title = element_text(size = 14, face = "bold")).

Rotate and realign a label

element_text() also positions the title. Use angle = to rotate it and hjust / vjust (each a number in [0, 1]) to align it. Here we un-rotate the y-title to read horizontally and left-align the x-title.

library(ggplot2)
ggplot(ToothGrowth, aes(x = factor(dose), y = len)) +
  geom_boxplot(fill = "#3a86d4", alpha = 0.7) +
  labs(x = "Dose (mg/day)", y = "Tooth length") +
  theme_minimal() +
  theme(
    axis.title.x = element_text(hjust = 0),
    axis.title.y = element_text(angle = 0, vjust = 0.5)
  )

ggplot2 box plot with the y-axis title rotated to horizontal and the x-axis title left-aligned.

For the x-title, hjust = 0 places it on the left, hjust = 0.5 centres it (the default), and hjust = 1 pushes it right. For a multi-line title, add lineheight = to control the spacing between lines.

Remove an axis label

Two ways to drop a title. The quick one is labs(x = NULL), which removes just that title’s text. To suppress it through the theme instead, set the element to element_blank().

library(ggplot2)
ggplot(ToothGrowth, aes(x = factor(dose), y = len)) +
  geom_boxplot(fill = "#3a86d4", alpha = 0.7) +
  labs(x = NULL, y = "Tooth length") +
  theme_minimal() +
  theme(axis.title.x = element_blank())

ggplot2 box plot with the x-axis title removed while the y-axis title Tooth length remains.

To remove both titles at once, blank the parent element: theme(axis.title = element_blank()). Removing the title leaves the tick labels in place — to change those, see the axis ticks lesson.

Try it live

The plots above were rendered at build time. Want to experiment? Edit the code and press Run — it executes in your browser via webR (no server, no install).

🟢 With an AI agent

Ask Prova “rename and restyle the x and y axis titles on my ggplot2 chart” — it answers with code you can run on your own plot, so the recipe is reproducible. The runtime is the judge. Ask Prova →

Frequently asked questions

Add labs(x = "New x title", y = "New y title") to your plot. labs() sets both axis titles in one call and can also set the plot title, subtitle, and caption.

They do the same thing. xlab("...") is shorthand for labs(x = "...") and ylab("...") for labs(y = "..."). Prefer labs() because it sets both axes (and the title/subtitle) in a single tidy call; xlab()/ylab() are single-purpose equivalents you will still meet in older code.

Style it in theme() with element_text(): theme(axis.title.x = element_text(colour = "blue", size = 14, face = "bold")). Use axis.title.y for the y-axis or axis.title to style both at once. Allowed faces are "plain", "bold", "italic", and "bold.italic".

Use labs(x = NULL) to drop the x-axis title’s text, or theme(axis.title.x = element_blank()) through the theme. To remove both titles at once, set theme(axis.title = element_blank()). This removes the title only — the tick labels stay.

Rotate it with angle = inside element_text(), e.g. theme(axis.title.y = element_text(angle = 0, vjust = 0.5)) to make the y-title read horizontally. Note this rotates the axis title; to rotate the tick labels use axis.text.x instead (see the axis ticks lesson).

Test your understanding

Complete the code so the x-axis reads “Dose level”, the y-axis reads “Tooth length”, and both titles are bold.

# labs(x = "Dose level", y = "Tooth length") sets the two titles;
# axis.title = element_text(face = "bold") makes both bold at once.
library(ggplot2) ggplot(ToothGrowth, aes(x = factor(dose), y = len)) + geom_boxplot(fill = "#3a86d4", alpha = 0.7) + labs(x = "Dose level", y = "Tooth length") + theme_minimal() + theme(axis.title = element_text(face = "bold"))
library(ggplot2)
ggplot(ToothGrowth, aes(x = factor(dose), y = len)) +
  geom_boxplot(fill = "#3a86d4", alpha = 0.7) +
  labs(x = "Dose level", y = "Tooth length") +
  theme_minimal() +
  theme(axis.title = element_text(face = "bold"))

Quick check: which function removes an axis title’s text without touching the tick labels?

labs(x = NULL) (or theme(axis.title.x = element_blank())). Both drop the axis title only; the tick labels beside each mark stay in place.

Conclusion

You set both axis titles in one call with labs(x =, y =), changed just one, restyled a title’s colour, size, and face with theme(axis.title.x = element_text(...)), rotated and realigned it with angle and hjust/vjust, and removed a title with labs(x = NULL) or element_blank(). Remember the split: labs() sets the text, theme() sets the look.

Reuse

Citation

BibTeX citation:
@online{2026,
  author = {},
  title = {Change {Axis} {Labels} in {R:} {A} Ggplot2 {Guide}},
  date = {2026-07-08},
  url = {https://www.datanovia.com/learn/data-visualization/ggplot2/axis-labels},
  langid = {en}
}
For attribution, please cite this work as:
“Change Axis Labels in R: A Ggplot2 Guide.” 2026. July 8. https://www.datanovia.com/learn/data-visualization/ggplot2/axis-labels.