ggplot2 guides() in R: Customize Legend and Axis Guides

The ggplot2 guides() function in R modifies the legends and axis guides attached to scales. Use it to hide a legend, rename it, reorder its entries, or swap between a discrete legend, continuous colorbar, or binned colorsteps.

⚡ Quick Answer
guides(color = "none")                                     # hide one legend
guides(color = guide_legend(title = "Cylinders"))          # rename legend
guides(color = guide_legend(ncol = 2))                     # multi-column
guides(color = guide_legend(reverse = TRUE))               # reverse order
guides(color = guide_colorbar(barwidth = 10))              # continuous bar
guides(fill = guide_colorsteps())                           # binned colors
guides(x = guide_axis(angle = 45))                          # rotated axis

Need explanation? Read on for examples and pitfalls.

📊 Is guides() the right tool?
STARThide or rename a legendguides(aes = "none" or guide_legend())move the legend on the pagetheme(legend.position = ...)change the colors themselvesscale_color_manual()restyle legend text and backgroundtheme(legend.text = ...)drop unused factor levels from legendscale_color_discrete(drop = FALSE)override aesthetics shown in legendguide_legend(override.aes = list(...))

What guides() does in one sentence

guides() is the high-level entry point for changing every visual aspect of legends and axes that ggplot2 builds from scales. Each aesthetic in your plot (color, fill, size, shape, x, y) gets a default guide; guides() lets you replace those defaults with guide_legend(), guide_colorbar(), guide_colorsteps(), guide_axis(), or the special string "none".

Note
guides() controls WHAT the legend shows; theme() controls HOW it looks. Title text, key shape, item order belong to guides(). Position, font, background colour belong to theme().

Syntax

guides(<aesthetic> = <guide_function or "none">, ...). One named argument per aesthetic you want to override.

Run live
Run live, no install needed. Every R block on this page runs in your browser. Click Run, edit the code, re-run instantly. No setup.
RBasic guides call
library(ggplot2) ggplot(mtcars, aes(wt, mpg, color = factor(cyl), size = hp)) + geom_point() + guides( color = guide_legend(title = "Cylinders", order = 1), size = guide_legend(title = "Horsepower", order = 2) )

  

Each argument name matches an aesthetic in your plot. Values can be a guide constructor (guide_legend(), guide_colorbar(), etc.) or the literal string "none" to suppress that legend.

Five common patterns

1. Hide a single legend

RSuppress color legend
ggplot(mtcars, aes(wt, mpg, color = factor(cyl))) + geom_point(size = 3) + guides(color = "none")

  

This keeps the color mapping but drops the legend block. Useful when the color encoding is decorative or already explained in a caption.

2. Rename and reorder legend entries

RTitle plus manual order
ggplot(mtcars, aes(wt, mpg, color = factor(cyl))) + geom_point(size = 3) + guides(color = guide_legend(title = "Cylinders", reverse = TRUE))

  

reverse = TRUE flips the order without touching the data. Pair with factor(..., levels = c(...)) if you need a fully custom order.

3. Multi-column legends

RTwo-column legend
ggplot(mtcars, aes(wt, mpg, color = factor(gear))) + geom_point(size = 3) + guides(color = guide_legend(ncol = 2, byrow = TRUE))

  

ncol, nrow, and byrow lay out long legends compactly. Combine with theme(legend.position = "bottom") for dashboards where vertical space is scarce.

4. Switch a continuous colorbar to discrete or binned

RUse colorsteps for binned color
ggplot(faithfuld, aes(waiting, eruptions, fill = density)) + geom_raster() + scale_fill_viridis_c() + guides(fill = guide_colorsteps(barwidth = 12, barheight = 0.6))

  

guide_colorsteps() snaps a continuous scale to discrete bins, easier to read than a smooth gradient when readers compare values across rows.

5. Override aesthetics shown in the legend

RForce visible point size in legend
ggplot(mtcars, aes(wt, mpg, color = factor(cyl))) + geom_point(alpha = 0.2, size = 2) + guides(color = guide_legend(override.aes = list(alpha = 1, size = 4)))

  

override.aes keeps faded, small points in the plot while showing solid, clearly-sized keys in the legend. The single most-asked pattern on Stack Overflow for legend appearance.

Key Insight
guides() operates on the SCALE, not the geom. That is why a single guides(color = ...) call affects every layer that maps to color, and why setting color = "red" inside geom_point() (no scale, no legend) cannot be controlled with guides().

Choosing the right guide function

Guide constructor Use when Default for
guide_legend() Discrete scales (factor, character) scale_color_discrete()
guide_colorbar() Continuous scales, smooth gradient scale_color_continuous()
guide_colorsteps() Continuous scale, binned readout scale_color_steps()
guide_bins() Discrete bins from cut continuous scale_color_binned()
guide_axis() x or y axis ticks and labels every position scale
"none" Suppress the guide none
Tip
Set the guide on the scale instead with scale_color_*(guide = guide_legend(...)) to keep the guide and scale change in one block. Functionally identical to guides(); just a style preference.

guides() vs theme() vs scale_*()

Three functions touch every customized legend; each owns a different slice. guides() picks the guide and shapes its contents. theme() styles the container. scale_*() controls the data-to-aesthetic mapping itself.

Function Controls Example
guides() Which guide; legend structure guides(color = guide_legend(ncol = 2))
theme() Visual styling of legend container theme(legend.position = "bottom")
scale_*() Color values, breaks, labels scale_color_viridis_d()

A well-styled plot usually touches all three: scale_*() picks the palette, guides() chooses the guide shape, theme() places and styles it.

A practical workflow

Build the plot first, then layer guides() and theme() last.

REnd-to-end legend customization
library(ggplot2) p <- ggplot(mtcars, aes(wt, mpg, color = factor(cyl))) + geom_point(size = 3, alpha = 0.8) + scale_color_brewer(palette = "Set1") + labs(title = "Fuel economy by weight") p + guides(color = guide_legend( title = "Cylinders", ncol = 3, reverse = TRUE, override.aes = list(size = 5) )) + theme(legend.position = "bottom")

  

This pattern, build, then style, makes legend tweaks reversible without re-fitting the plot.

Common pitfalls

Pitfall 1: guides(color = FALSE) is deprecated. Use guides(color = "none") in ggplot2 3.3.4 or newer. The boolean form still works but emits a warning.

Pitfall 2: Hiding the wrong aesthetic. If both color and fill map to the same variable, two legends appear; guides(color = "none") hides only one. Suppress both, or set show.legend = FALSE on the geom.

Pitfall 3: Trying to move the legend with guides(). Position is a theme() concern: theme(legend.position = "top"). guides() cannot move a legend.

Try it yourself

Try it: On iris, plot Sepal.Length vs Petal.Length colored by Species. Rename the legend title to "Species", reverse the order, and force a 4 point legend key.

RYour turn: customize iris legend
# Try it: customize iris legend ex_plot <- ggplot(iris, aes(Sepal.Length, Petal.Length, color = Species)) + geom_point(size = 2, alpha = 0.5) + # your code here ex_plot #> Expected: legend titled "Species", reversed order, solid points size 4

  
Click to reveal solution
RSolution
ex_plot <- ggplot(iris, aes(Sepal.Length, Petal.Length, color = Species)) + geom_point(size = 2, alpha = 0.5) + guides(color = guide_legend( title = "Species", reverse = TRUE, override.aes = list(alpha = 1, size = 4) )) ex_plot

  

Explanation: guide_legend() accepts title, reverse, and override.aes together. The override keeps faded points in the plot while drawing crisp keys in the legend.

  • guide_legend(), guide_colorbar(), guide_colorsteps(), guide_axis(): individual guide constructors called inside guides()
  • scale_color_manual(), scale_fill_viridis_c(): control color values; pass a guide argument for the same effect as guides()
  • theme(): position, font, background of legend container
  • labs(): shortcut for legend titles when no other guide tweaks are needed
  • See the official ggplot2 guides reference for every argument

FAQ

How do I remove all legends from a ggplot2 plot at once?

Use theme(legend.position = "none") for a blanket suppression. guides() is per-aesthetic, so removing every legend through guides() would mean naming each aesthetic explicitly. The theme() shortcut is shorter and works regardless of which aesthetics you mapped.

What is the difference between guides() and guide_legend()?

guides() is the wrapper that takes one entry per aesthetic. guide_legend() is one of several guide constructors you pass into it. You can also assign guide_legend() directly to a scale via scale_color_discrete(guide = guide_legend(...)), which is functionally identical.

Can guides() change the legend title alone?

Yes, with guides(color = guide_legend(title = "My title")). The shorter labs(color = "My title") does the same job when title is the only change. Reach for guides() when you also want to set ncol, reverse, or override.aes in the same call.

Why does my legend show a half-transparent point when the plot points are crisp?

The legend mirrors the geom mapping by default, including alpha. Use guides(color = guide_legend(override.aes = list(alpha = 1))) to force the legend keys to be opaque while leaving the plot points faded.

Does guides() work on facets?

Yes. Facets do not create their own legends; the guide attached to the color, fill, size, or shape scale is shared across all facet panels. guides() controls that shared guide just as it would in a non-faceted plot.