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.
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.
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".
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.
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
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
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
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
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
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.
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 |
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.
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.
Click to reveal solution
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.
Related ggplot2 functions
guide_legend(),guide_colorbar(),guide_colorsteps(),guide_axis(): individual guide constructors called insideguides()scale_color_manual(),scale_fill_viridis_c(): control color values; pass aguideargument for the same effect asguides()theme(): position, font, background of legend containerlabs(): 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.