Skip to contents

Overview

When a plot maps multiple aesthetics (colour, size, shape, etc.), ggplot2 creates separate legends for each. ggguides provides functions to control these legends individually:

Example Plot

# 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")

p
fill: #F5F6F8;' /> fill: #F5F6F8;' /> 2 3 4 5 10 15 20 25 30 35 mpg wt fill: #F5F6F8;' /> fill: #F5F6F8;' /> Cylinders fill: #F5F6F8;' /> fill: #F5F6F8;' /> fill: #F5F6F8;' /> 4 6 8 fill: #F5F6F8;' /> Transmission fill: #F5F6F8;' /> fill: #F5F6F8;' /> 0 1 fill: #F5F6F8;' /> Horsepower fill: #F5F6F8;' /> fill: #F5F6F8;' /> fill: #F5F6F8;' /> fill: #F5F6F8;' /> fill: #F5F6F8;' /> 100 150 200 250 300

Hiding Legends

Use legend_hide() to remove specific legends while keeping others:

# Hide the size legend
p + legend_hide(size)
fill: #F5F6F8;' /> fill: #F5F6F8;' /> 2 3 4 5 10 15 20 25 30 35 mpg wt fill: #F5F6F8;' /> fill: #F5F6F8;' /> Cylinders fill: #F5F6F8;' /> fill: #F5F6F8;' /> fill: #F5F6F8;' /> 4 6 8 fill: #F5F6F8;' /> Transmission fill: #F5F6F8;' /> fill: #F5F6F8;' /> 0 1

# Hide multiple legends
p + legend_hide(size, shape)
fill: #F5F6F8;' /> fill: #F5F6F8;' /> 2 3 4 5 10 15 20 25 30 35 mpg wt fill: #F5F6F8;' /> fill: #F5F6F8;' /> Cylinders fill: #F5F6F8;' /> fill: #F5F6F8;' /> fill: #F5F6F8;' /> 4 6 8

Selecting Legends

Use legend_select() to keep only certain legends (inverse of legend_hide()):

# Keep only the colour legend
p + legend_select(colour)
fill: #F5F6F8;' /> fill: #F5F6F8;' /> 2 3 4 5 10 15 20 25 30 35 mpg wt fill: #F5F6F8;' /> fill: #F5F6F8;' /> Cylinders fill: #F5F6F8;' /> fill: #F5F6F8;' /> fill: #F5F6F8;' /> 4 6 8

# Keep colour and shape
p + legend_select(colour, shape)
fill: #F5F6F8;' /> fill: #F5F6F8;' /> 2 3 4 5 10 15 20 25 30 35 mpg wt fill: #F5F6F8;' /> fill: #F5F6F8;' /> Cylinders fill: #F5F6F8;' /> fill: #F5F6F8;' /> fill: #F5F6F8;' /> 4 6 8 fill: #F5F6F8;' /> Transmission fill: #F5F6F8;' /> fill: #F5F6F8;' /> 0 1

Controlling Legend Order

By default, legends appear in an unspecified order. Use legend_order_guides() to control the display order:

# Default order
p
fill: #F5F6F8;' /> fill: #F5F6F8;' /> 2 3 4 5 10 15 20 25 30 35 mpg wt fill: #F5F6F8;' /> fill: #F5F6F8;' /> Cylinders fill: #F5F6F8;' /> fill: #F5F6F8;' /> fill: #F5F6F8;' /> 4 6 8 fill: #F5F6F8;' /> Transmission fill: #F5F6F8;' /> fill: #F5F6F8;' /> 0 1 fill: #F5F6F8;' /> Horsepower fill: #F5F6F8;' /> fill: #F5F6F8;' /> fill: #F5F6F8;' /> fill: #F5F6F8;' /> fill: #F5F6F8;' /> 100 150 200 250 300

# Size legend first, then colour, then shape
p + legend_order_guides(size = 1, colour = 2, shape = 3)
fill: #F5F6F8;' /> fill: #F5F6F8;' /> 2 3 4 5 10 15 20 25 30 35 mpg wt fill: #F5F6F8;' /> fill: #F5F6F8;' /> Horsepower fill: #F5F6F8;' /> fill: #F5F6F8;' /> fill: #F5F6F8;' /> fill: #F5F6F8;' /> fill: #F5F6F8;' /> 100 150 200 250 300 fill: #F5F6F8;' /> Cylinders fill: #F5F6F8;' /> fill: #F5F6F8;' /> fill: #F5F6F8;' /> 4 6 8 fill: #F5F6F8;' /> Transmission fill: #F5F6F8;' /> fill: #F5F6F8;' /> 0 1

Merging and Splitting Legends

ggplot2 automatically merges legends when they have the same title and matching labels. Use legend_merge() and legend_split() to override this behavior.

Forcing Merge

# 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_merge
fill: #F5F6F8;' /> fill: #F5F6F8;' /> 2 3 4 5 10 15 20 25 30 35 mpg wt fill: #F5F6F8;' /> fill: #F5F6F8;' /> Cylinders fill: #F5F6F8;' /> fill: #F5F6F8;' /> fill: #F5F6F8;' /> 4 6 8

# Explicitly request merge (reinforces default behavior)
p_merge + legend_merge(colour, fill)
fill: #F5F6F8;' /> fill: #F5F6F8;' /> 2 3 4 5 10 15 20 25 30 35 mpg wt fill: #F5F6F8;' /> fill: #F5F6F8;' /> Cylinders fill: #F5F6F8;' /> fill: #F5F6F8;' /> fill: #F5F6F8;' /> 4 6 8

Forcing Split

# Force separate legends even when they could merge
p_merge + legend_split(colour, fill)
fill: #F5F6F8;' /> fill: #F5F6F8;' /> 2 3 4 5 10 15 20 25 30 35 mpg wt fill: #F5F6F8;' /> fill: #F5F6F8;' /> Cylinders fill: #F5F6F8;' /> fill: #F5F6F8;' /> fill: #F5F6F8;' /> 4 6 8 fill: #F5F6F8;' /> Cylinders fill: #F5F6F8;' /> fill: #F5F6F8;' /> fill: #F5F6F8;' /> 4 6 8

Positioning Legends Separately

Position 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")
fill: #F5F6F8;' /> fill: #F5F6F8;' /> 2 3 4 5 10 15 20 25 30 35 mpg wt fill: #F5F6F8;' /> fill: #F5F6F8;' /> Cylinders fill: #F5F6F8;' /> fill: #F5F6F8;' /> fill: #F5F6F8;' /> 4 6 8 fill: #F5F6F8;' /> fill: #F5F6F8;' /> Horsepower fill: #F5F6F8;' /> fill: #F5F6F8;' /> fill: #F5F6F8;' /> fill: #F5F6F8;' /> fill: #F5F6F8;' /> 100 150 200 250 300
# Colour legend on top, size on right
p +
  legend_hide(shape) +
  legend_top(by = "colour") +
  legend_right(by = "size")
fill: #F5F6F8;' /> fill: #F5F6F8;' /> 2 3 4 5 10 15 20 25 30 35 mpg wt fill: #F5F6F8;' /> fill: #F5F6F8;' /> Horsepower fill: #F5F6F8;' /> fill: #F5F6F8;' /> fill: #F5F6F8;' /> fill: #F5F6F8;' /> fill: #F5F6F8;' /> 100 150 200 250 300 fill: #F5F6F8;' /> fill: #F5F6F8;' /> Cylinders fill: #F5F6F8;' /> fill: #F5F6F8;' /> fill: #F5F6F8;' /> 4 6 8

Styling Legends Separately

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")
fill: #F5F6F8;' /> fill: #F5F6F8;' /> 2 3 4 5 10 15 20 25 30 35 mpg wt fill: #F5F6F8;' /> Cylinders fill: #F5F6F8;' /> fill: #F5F6F8;' /> fill: #F5F6F8;' /> 4 6 8 fill: #F5F6F8;' /> Horsepower fill: #F5F6F8;' /> fill: #F5F6F8;' /> fill: #F5F6F8;' /> fill: #F5F6F8;' /> fill: #F5F6F8;' /> 100 150 200 250 300

Combining Multiple Controls

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")
fill: #F5F6F8;' /> fill: #F5F6F8;' /> 2 3 4 5 10 15 20 25 30 35 mpg wt fill: #F5F6F8;' /> fill: #F5F6F8;' /> Cylinders fill: #F5F6F8;' /> fill: #F5F6F8;' /> fill: #F5F6F8;' /> 4 6 8 fill: #F5F6F8;' /> Horsepower fill: #F5F6F8;' /> fill: #F5F6F8;' /> fill: #F5F6F8;' /> fill: #F5F6F8;' /> fill: #F5F6F8;' /> 100 150 200 250 300

Summary

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: