3

I am doing a plot with two different mappings ("group" is mapped to color and linetype and "to" is mapped to shape). I would like to combine those two mappings in a single legend but can't get the shape right in the legend.
Here's my try:

set.seed(123)
plotdata = cbind.data.frame(x = rep(1:5, times = 4), 
                            y = rnorm(20), 
                            from = rep(c("1","2"), each = 10),
                            to = rep(c("1","2"), times= 10))
plotdata = cbind.data.frame(plotdata, group = paste0(plotdata$from, "to", plotdata$to))

library(ggplot2)

plot1 = ggplot(plotdata, aes(x = x, y = y, group = group, color = group, lty = group, shape = to)) +
  geom_point() + geom_line() + theme_bw() + 
  scale_color_discrete(name = "", 
                       breaks = c("1to1", "1to2", "2to1", "2to2"), 
                       labels = c("1to1", "1to2", "2to1", "2to2")) +
  scale_linetype_discrete(name = "", 
                          breaks = c("1to1", "1to2", "2to1", "2to2"), 
                          labels = c("1to1", "1to2", "2to1", "2to2")) +
  scale_shape_manual(name = "", 
                     values = c(1, 2, 1, 2),
                     breaks = c("1to1", "1to2", "2to1", "2to2"), 
                     labels = c("1to1", "1to2", "2to1", "2to2"))
print(plot1)

plot

As you can see in the plot I have one legend but the shape is always a circle.
Desired behaviour: shape in the legend alternates between circle and pyramid as in the plot.

What I have tried so far was to specify the shape manually but that did not help as you can see above. I also looked at my plot object hoping to be able to manipulate it but to no avail.

mts
  • 2,160
  • 2
  • 24
  • 34

2 Answers2

5

You can get a single legend without override.aes. Just set shape=group as well, and use scale_shape_manual to set the repeating shape values. In this case, you don't need to map to to anything, because the information it contains is redundant:

ggplot(plotdata, aes(x = x, y = y, group = group, color = group, lty = group, 
                     shape = group)) +
  geom_point() + geom_line() + theme_bw() + 
  scale_color_discrete(name = "") +
  scale_linetype_discrete(name = "") +
  scale_shape_manual(name = "", values=c(1,2,1,2))

enter image description here

eipi10
  • 91,525
  • 24
  • 209
  • 285
3

This Q&A helped me out: you need to specify the shape explicitly in the color legend with 'override.aes':

plot1 = ggplot(plotdata, aes(x = x, y = y, group = group, color = group, lty = group, shape = to)) +
  geom_point() + geom_line() + theme_bw() + 
  scale_color_discrete(name = "", 
                       breaks = c("1to1", "1to2", "2to1", "2to2"), 
                       labels = c("1to1", "1to2", "2to1", "2to2"), 
                       guide = guide_legend(override.aes = list(shape = rep(c(1, 2), 2)))) +
  scale_linetype_discrete(name = "", 
                          breaks = c("1to1", "1to2", "2to1", "2to2"), 
                          labels = c("1to1", "1to2", "2to1", "2to2")) +
  scale_shape_discrete(guide = F)
plot1

enter image description here

Note however that you do need to figure out the correct shapes yourself. A reference might come handy.

Community
  • 1
  • 1
mts
  • 2,160
  • 2
  • 24
  • 34