Jenna Hamlin
Jenna Hamlin

Reputation: 45

make a common legend and include unique legend attributes

I am attempting to combine a legend for two plots with a shared blue line and unique bar colors (read and yellow). When plotting the code below only two of the three colored id's show up in the combined legend (red and blue) but I want the third color to show up as well in the combined legend.

For example

Here the line is a stand in for what I am using for a moving average. I don't think facet wrapping this will work as there are additional variable parameters in my code (i.e. scale_y_continuous that have different secondary axis scales) but below is a reproducible example of the basic idea.

library(datasets)
library(ggplot2)
library(cowplot)
data(beavers)

colour <- c("bevTemp1" = "red", "line" = "blue", "bevTemp2" = "yellow" )

bev1 <- ggplot(beaver1, aes(x=time, y = temp)) + 
  geom_bar(stat = "identity", aes(colour = "bevTemp1"), fill = "red")+ 
  coord_cartesian(ylim = c(35, 38)) +
  geom_line(size = 1.5, aes(color = "line"))+
  scale_color_manual(values = colour, 
                     guide = guide_legend(override.aes = list(
                       border=c(NA, NA),
                       fill=c("red","blue"))))+
  theme(legend.title = element_blank(), legend.position = "none")
  


bev2<- ggplot(beaver2, aes(x=time, y = temp)) + 
  geom_bar(stat = "identity", aes(colour = "bevTemp2"), fill = "yellow")+ 
  coord_cartesian(ylim = c(35, 38)) +
  geom_line(size = 1.5, aes(color = "line"))+
  scale_color_manual(values = colour, 
                     guide = guide_legend(override.aes = list(
                       border=c(NA, NA),
                       fill=c("yellow","blue"))))+
  theme(legend.title = element_blank(), legend.position = "none")

cowplot::plot_grid(
  cowplot::plot_grid(
    bev1 ,
    bev2,
    align = 'h'),
  cowplot::get_legend(bev1 +  theme(legend.position = "bottom")),
  nrow = 2, rel_heights = c(4, 1))

Suggestions...

Upvotes: 0

Views: 219

Answers (2)

starja
starja

Reputation: 10375

get_legend just retrieves the legend from the plot passed to this function, here bev1. So you need to also show bev2Temp in the legend of plot 1. You can add an additional id column to your dataset, make it a factor variable but in both datasets include bevTemp1/bevTemp2 as levels. In ggplot in scale_fill_manual, if you set drop = FALSE, all levels are shown:

library(datasets)
library(ggplot2)
library(cowplot)
data(beavers)

colour <- c("bevTemp1" = "red", "bevTemp2" = "yellow")
beaver1$id <- "bevTemp1"
beaver1$id <- factor(beaver1$id, levels = c("bevTemp1", "bevTemp2"))

beaver2$id <- "bevTemp2"
beaver2$id <- factor(beaver2$id, levels = c("bevTemp1", "bevTemp2"))


bev1 <- ggplot(beaver1, aes(x=time, y = temp, fill = id)) + 
  geom_bar(stat = "identity")+ 
  coord_cartesian(ylim = c(35, 38)) +
  geom_line(size = 1.5, aes(color = "line"))+
  theme(legend.title = element_blank(), legend.position = "none") +
  scale_fill_manual(values = c("bevTemp1" = "red", "bevTemp2" = "yellow"),
                    drop = FALSE) +
  scale_colour_manual(values = c("line" = "blue"))



bev2<- ggplot(beaver2, aes(x=time, y = temp, fill = id)) + 
  geom_bar(stat = "identity")+ 
  coord_cartesian(ylim = c(35, 38)) +
  geom_line(size = 1.5, aes(color = "line"))+
  theme(legend.title = element_blank(), legend.position = "none") +
  scale_fill_manual(values = c("bevTemp1" = "red", "bevTemp2" = "yellow"),
                    drop = FALSE) +
  scale_colour_manual(values = c("line" = "blue"))

cowplot::plot_grid(
  cowplot::plot_grid(
    bev1 ,
    bev2,
    align = 'h'),
  cowplot::get_legend(bev1 +  theme(legend.position = "bottom")),
  nrow = 2, rel_heights = c(4, 1))

enter image description here

Upvotes: 1

You could build a dummy plot just to get the desired legend and add it to the final plot. I would also suggest using the line legend for the geom_line.

library(ggplot2)

# Create dummy data
df <- data.frame(class = c("bevTemp1","bevTemp2"),
                 x = 1:2,
                 y = 2:3)

# Create dummy plot just to extract the desired legend
p1<- ggplot(df, aes(x=x,y=y)) + 
  geom_col(aes(fill = class))+
  geom_line(aes(col = "line"), size = 1.5)+  
  scale_fill_manual(values = c("red","yellow")) +
  scale_color_manual(values = "blue")+
  theme(legend.title = element_blank())

cowplot::plot_grid(
  cowplot::plot_grid(
    bev1 ,
    bev2,
    align = 'h'),
  # Add the legend of the dummy plot 
  cowplot::get_legend(p1 +  theme(legend.position = "bottom")),
  nrow = 2, rel_heights = c(4, 1))

Final plot

Upvotes: 2

Related Questions