When a plot maps multiple aesthetics (colour, size, shape, etc.), ggplot2 creates separate legends for each. ggguides provides functions to control these legends individually:
Hide specific legends with
legend_hide()
Keep only certain legends with
legend_select()
Control display order with
legend_order_guides()
Force merge/split with
legend_merge() and legend_split()
Position legends separately using
by parameter on position functions
Style legends separately using by
parameter on legend_style()
# Plot with multiple aesthetics
p <- ggplot(mtcars, aes(mpg, wt,
color = factor(cyl),
size = hp,
shape = factor(am))) +
geom_point() +
labs(color = "Cylinders", size = "Horsepower", shape = "Transmission")
pUse legend_hide() to remove specific legends while
keeping others:
Use legend_select() to keep only certain legends
(inverse of legend_hide()):
By default, legends appear in an unspecified order. Use
legend_order_guides() to control the display order:
# Size legend first, then colour, then shape
p + legend_order_guides(size = 1, colour = 2, shape = 3)ggplot2 automatically merges legends when they have the same title
and matching labels. Use legend_merge() and
legend_split() to override this behavior.
# Plot where colour and fill map to the same variable
p_merge <- ggplot(mtcars, aes(mpg, wt, color = factor(cyl), fill = factor(cyl))) +
geom_point(shape = 21, size = 4, stroke = 1.5) +
labs(color = "Cylinders", fill = "Cylinders")
# Legends merge automatically when titles and labels match
p_mergePosition functions (legend_left(),
legend_right(), legend_top(),
legend_bottom()) accept a by parameter to
position specific legends:
# Place colour legend on the left, size legend at bottom
p +
legend_hide(shape) +
legend_left(by = "colour") +
legend_bottom(by = "size")# Colour legend on top, size on right
p +
legend_hide(shape) +
legend_top(by = "colour") +
legend_right(by = "size")Use the by parameter on legend_style() to
apply different styles to different legends:
p +
legend_hide(shape) +
legend_style(title_face = "bold", background = "grey95", by = "colour") +
legend_style(size = 10, by = "size")When a plot has four legends and you want one on each side (top, bottom, left, right), you can fine-tune each legend along three axes:
Side placement —
legend_top/bottom/left/right(by = "<aes>")
Distance from the panel —
legend_style(by = "<aes>", margin = c(t, r, b, l))
Slide along the side —
legend_style(by = "<aes>", justification = ...)
For top/bottom legends, justification is
"left", "center", "right" (or a
number in [0, 1]). For left/right legends, it’s
"top", "center", "bottom" (or a
number).
p4 <- ggplot(mtcars, aes(mpg, wt,
colour = factor(cyl),
fill = factor(gear),
size = hp,
shape = factor(am))) +
geom_point(stroke = 1.2) +
labs(colour = "Cyl", fill = "Gear", size = "HP", shape = "AM")
p4 +
# 1. Send each legend to its side
legend_top (by = "colour") +
legend_bottom(by = "fill") +
legend_left (by = "size") +
legend_right (by = "shape") +
# 2. Slide each legend along its side
legend_style(by = "colour", justification = "left") +
legend_style(by = "fill", justification = "right") +
legend_style(by = "size", justification = "top") +
legend_style(by = "shape", justification = "bottom") +
# 3. Nudge each legend toward/away from the panel via margin (cm)
legend_style(by = "colour", margin = c(0, 0, 0.3, 0)) +
legend_style(by = "fill", margin = c(0.3, 0, 0, 0)) +
legend_style(by = "size", margin = c(0, 0.3, 0, 0)) +
legend_style(by = "shape", margin = c(0, 0, 0, 0.3))Each legend_style(by = ...) call is additive — you can
chain as many as you need to tune one legend at a time without affecting
the others.
All functions work together:
# Complex example: hide shape, position colour on left with bold title,
# position size at bottom with smaller text
p +
legend_hide(shape) +
legend_left(by = "colour") +
legend_style(title_face = "bold", title_size = 14, by = "colour") +
legend_bottom(by = "size") +
legend_style(size = 9, direction = "horizontal", by = "size")| Function | Purpose | Parameters |
|---|---|---|
legend_hide() |
Hide specific legends | Aesthetic names (unquoted) |
legend_select() |
Keep only specific legends | Aesthetic names (unquoted) |
legend_order_guides() |
Control legend display order | Named args: aes = order |
legend_merge() |
Force legends to merge | Aesthetic names (unquoted) |
legend_split() |
Force legends to stay separate | Aesthetic names (unquoted) |
legend_left(by=) |
Position one legend on left | by = "aesthetic" |
legend_style(by=) |
Style one legend | by = "aesthetic" + style args |
Learn more:
Legend Positioning for single-legend placement
Styling & Customization for legend appearance
Patchwork Integration for multi-panel plots