Skip to main content
v2026.11,858 entries · CC-BY 4.0
LAC HealthMedical & Research SuppliesReagents, PPE & instruments — chain-of-custody documented.Fast, traceable sourcing built for regulated research environments, from bench consumables to instrumentation.Shop lac.us CodeCASRAIlac.us

Label Legend in ggplot2: Change Legend Labels and Keys

How to label a legend in ggplot2: relabel keys on the right scale, keep labels matched to colours, and reorder, hide or lay out the legend.

Written and maintained by CASRAI Editorial Board

Last updated

To label a legend in ggplot2, change the labels on the scale that draws that legend: pass a character vector to the labels argument of the scale for the aesthetic you mapped (for example scale_colour_discrete(labels = ...) for colour). Changing the legend text any other way, such as editing the plot title or the axis, leaves the legend untouched. This guide covers the safe way to relabel legend keys so the right text stays attached to the right colour, how to fix labels in the data itself, and how to reorder, hide and lay out the keys. The legend title is a separate topic, covered in ggplot titles.

What it is used for in research

Raw data columns often hold codes such as 4, 6 and 8, or group names such as ctrl and trt1. A figure submitted to a journal or shared with collaborators needs readable legend keys (“four cylinders”, “Control”, “Treatment 1”) without altering the underlying dataset. Legend labels are also where silent mistakes happen: a label vector in the wrong order attaches the wrong text to a colour and the figure still renders with no error. The sections below are arranged to prevent that.

Install or access (official source only)

ggplot2 is an R package distributed through CRAN and documented at the tidyverse reference site, ggplot2.tidyverse.org/reference. From the R console:

install.packages("ggplot2")
library(ggplot2)

It is also installed as part of the tidyverse collection. The examples below use the mtcars data set that ships with R, so they run without any extra files.

Step-by-step: change legend labels with a scale

The legend for an aesthetic is produced by that aesthetic’s scale, so labels belong on the scale. The ggplot2 reference for scale_manual defines the labels argument as: NULL for no labels, waiver() for the default labels, a character vector giving labels that must be the same length as breaks, or a function that takes the breaks as input and returns labels as output.

  1. Build the plot and map the aesthetic.
    p <- ggplot(mtcars, aes(wt, mpg, colour = factor(cyl))) +
      geom_point()
  2. Add the scale for that aesthetic and pass labels. Because colour is mapped, use a colour scale:
    p + scale_colour_discrete(labels = c("four", "six", "eight"))
  3. Set breaks together with labels when you can. The scale reference states that it is highly recommended to also set the breaks argument as a vector. With a manual scale, the official example pairs all three arguments:
    cols <- c("4" = "#1b9e77", "6" = "#d95f02", "8" = "#7570b3")
    p + scale_colour_manual(values = cols,
                            breaks = c("4", "6", "8"),
                            labels = c("four", "six", "eight"))
  4. Use a function when the label is a rule, not a list.
    p + scale_colour_discrete(labels = function(x) paste(x, "cylinders"))

Which scale to target

The scale must match the aesthetic you mapped. Adding a fill scale to a plot whose legend comes from colour changes nothing, and no error is raised.

You mapped Relabel with Typical geoms
colour scale_colour_discrete() or scale_colour_manual() points, lines, box outlines
fill scale_fill_discrete() or scale_fill_manual() bars, boxplots, areas
shape scale_shape_discrete() or scale_shape_manual() points
Several aesthetics at once scale_discrete_manual(aesthetics = c("colour", "fill"), ...) any

The reference shows the general form as scale_discrete_manual(aesthetics, ..., values, breaks = waiver()). For colour choices themselves, see ggplot colour.

Keep labels attached to the right colours

With a manual scale, values can be a named vector. The reference states that when it is named, the values are matched on the names instead of on position. Naming the values (as cols does above) means a later change in the order of the data cannot move a colour onto the wrong group. Labels given as a plain character vector are still matched by position to breaks, which is why setting breaks explicitly matters.

Change labels by editing the factor levels

Scale labels fix one plot. If the same group names appear in several figures, relabel the data once and every legend, facet strip and axis follows:

mtcars$cyl_f <- factor(mtcars$cyl,
                       levels = c(4, 6, 8),
                       labels = c("four", "six", "eight"))
ggplot(mtcars, aes(wt, mpg, colour = cyl_f)) + geom_point()

The scale reference also describes limits as a character vector that defines the possible values of the scale and their order, so limits is the scale-level tool for ordering, while levels is the data-level tool.

Reorder, hide or lay out the legend keys

Guide settings

The signature in the ggplot2 reference is guide_legend(title = waiver(), theme = NULL, position = NULL, direction = NULL, override.aes = list(), nrow = NULL, ncol = NULL, reverse = FALSE, order = 0, ...). Useful arguments:

  • reverse = TRUE reverses the order; the reference describes it as a logical that, when TRUE, reverses the order of legends.
  • nrow and ncol set the number of rows and columns of keys.
  • override.aes takes a list of aesthetic parameters for the legend keys, for example list(size = 4) to enlarge small points in the legend only.
p + guides(colour = guide_legend(nrow = 1, reverse = TRUE,
                                 override.aes = list(size = 4)))

Remove a legend

The guides reference notes that guides can be set scale by scale with the guide argument or all together with guides(), and removes one with guides(colour = "none"). To keep the legend but drop its title, the scale name can be set to NULL.

Text size and position through the theme

The theme reference lists legend.text as the legend item labels (an element_text()), legend.key.size as the size of the keys (a unit), and legend.position as one of “none”, “left”, “right”, “bottom”, “top” or “inside”. For “inside”, legend.position.inside takes a numeric vector of length two.

p + theme(legend.position = "inside",
          legend.position.inside = c(0.9, 0.85),
          legend.text = element_text(size = 12))

Broader theme choices are in ggplot themes. Legend keys describe a mapped aesthetic; axis tick labels are a different set of labels and are changed on the axis scale, as covered in axis labels in R.

Output and how to read it

After a change, check three things on the rendered figure: each label sits beside the colour or shape it should (compare against a few points you can identify in the data), the number of keys equals the number of groups, and no second legend has appeared. If a second legend appears, check that every aesthetic mapped to the same variable has the same scale name and labels. For a wider overview of building figures, see ggplots in R.

Troubleshooting

Legend labels did not change

The scale probably targets a different aesthetic than the one mapped. If the plot maps fill, use scale_fill_*; if it maps colour, use scale_colour_*. Check the aes() call first.

Labels attached to the wrong colours

The label vector is matched by position. Set breaks explicitly alongside labels, use named values in manual scales, or relabel the factor levels in the data.

Error about label length

The reference requires a character vector of labels to be the same length as breaks. Count your groups, including any you removed with limits.

The labels changed but the axis text did not

Legend labels and axis labels belong to different scales. Use scale_x_discrete(labels = ...) for a discrete x axis.

Free alternatives

Tool Where legend labels are set
ggplot2 (R) labels argument of the aesthetic’s scale, as above
Base R graphics the legend argument of legend(), a character vector of the text to show
Matplotlib (Python) the legend text is set from the plot labels; see legend in Matplotlib

FAQ

How do I change ggplot legend labels?

Pass a character vector to labels in the scale for the mapped aesthetic, for example scale_colour_discrete(labels = c("four", "six", "eight")), and set breaks as well so the order cannot drift.

How do I label a legend in ggplot without editing my data?

Use the scale labels argument. It changes only the displayed text; the data frame is not modified.

How do I remove the legend entirely?

Use guides(colour = "none") for one aesthetic, or theme(legend.position = "none") for all legends.

Sources (official docs)

Follow CASRAI

Research-administration guidance, standards updates and independent tool reviews.

Ask CASRAI · free to try

Ask about Label Legend in ggplot2: Change Legend Labels and Keys

Ask your first 2 questions free below. Subscribers get 150 a day for $29 a month.

An AI assistant specialized in research administration. It cites the sources behind every answer, labels web answers and says when it can't answer.

Answers draw on CASRAI's guides and dictionary plus the federal and funder documents we index: Federal Register, Grants.gov, Regulations.gov and UKRI.

Works on this site and inside Claude, Cursor and the AI tools you already use.

Everything CASRAI publishes — this page, the dictionary, the guides and the news — stays free to read, with no account and no card.

Referenced across the research world

University of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logoUniversity of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logo
  • University of Cambridge logo
  • Columbia University logo
  • Crossref logo
  • University of Edinburgh logo
  • Harvard University logo
  • University of Oxford logo
  • Princeton University logo
  • Stanford School of Medicine logo
  • University College London logo
  • ORCID logo

View CASRAI adoption →