Search code examples
rggplot2legend

make ggplot legend correspond to geom type


Let's say I need to plot two sets ("types") of data with the same units, where each type has a group a and group b. I want group (a,b) to correspond to color, but I want the type (A, B) to correspond to the geom (say, path for A and point for B). How can I build a plot like this?

library(ggplot2)
library(dplyr)

set.seed(22)

# Example data
df <- data.frame(
  x = rep(1:10, 2),
  y = c(runif(10, 1, 3), runif(10, 3, 5)),
  pVar = rep(c("A", "B"), each = 10),
  cVar = rep(c("a", "b"), 10)
) %>%
  mutate(grp = paste(pVar, cVar, sep = "_"))

Solution

  • I would also use a fake alpha scale to get the nice legend, but I would first try pivoting to make two y-variables:

    library(ggplot2); library(tidyr)
    
    df |> 
      pivot_wider(id_cols = c(x, cVar), names_from = pVar, values_from = y) |> 
      ggplot(aes(x, color = cVar)) +
      geom_path(aes(y = A, alpha = 'A')) +
      geom_point(aes(y = B, alpha = 'B')) +
      scale_alpha_discrete(range = c(1, 1))
    

    enter image description here

    Otherwise I still find the data subsetting easier in general:

    ggplot(df, aes(x, y, color = cVar, alpha = pVar)) +
      geom_path(data = \(d) filter(d, pVar == 'A')) +
      geom_point(data = \(d) filter(d, pVar == 'B')) +
      scale_alpha_discrete(range = c(1, 1))
    

    enter image description here