Ben Ben - 3 months ago 23
R Question

Conditional legend symbols in ggplot2

I need to change the symbols in the legend of my ggplot according to some condition in the data. For example, here I want hollow circles for values of

cyl
greater than 4:

library(ggplot2)
ggplot()+
geom_point(data = mtcars[mtcars$gear >= 4,],
aes(mpg,
disp,
size = gear),
pch = 21) +
geom_point(data = mtcars[mtcars$gear < 4,],
aes(mpg,
disp,
size = gear)) +
theme_minimal() +
guides(size = guide_legend(override.aes = list(pch = c(19, 19, 21, 21, 21))))


enter image description here

My current method is to hard-code a vector of shapes for the legend:
guides(size = guide_legend(override.aes = list(pch = c(19, 19, 21, 21, 21))))
.

But how can I avoid this hard-coding by automating and generalizing this so I can more easily make many plots where the data have different ranges and I need to change the legend to show different conditions?

Answer

If you find out what breaks are going to be used, then you can set a condition in the override.aes. For a continuous scale, I think the default is scales::cbreaks(DATA_RANGE, extended_breaks()).

library(ggplot2)
library(scales)

cutoff <- 4 # set the condition value here so we don't hard-code it in the plot code

ggplot(mtcars, aes(x = mpg, 
                   y = disp, 
                   size = gear, 
                   shape = gear >= cutoff)) +
  geom_point() +
  theme_minimal() +
  scale_shape_manual(values = c(19, 21),
                     name = "gear",
                     guide  = "none") +
  guides(size = guide_legend(override.aes = list(pch = ifelse(
    cbreaks(range(mtcars$gear), 
            extended_breaks())$breaks >= cutoff, 21, 19
  ))))