I am struggling to make a legend that I want for my graph. Here is what the graph currently looks like (it's not a final version, I know it's not super pretty)
I am frustrated by the fact that I can't seem to combine the legends into one using patchwork or ggarrange packages. I am used to using scale_fcn_manual() and making the aesthetic calls identical, then calling for "collected" legends in patchwork(). However, because the data within each plot is actually different, it is still making them into 3 separate plot legends, despite the fact that I have all possible treatment options in my code.
Does anyone know how to either create an entirely new legend from scratch or fix my code? I have tried using a common legend using ggarrange() as well, but got a similar result. Below, I will include my ggplot code and also what I would LIKE the figure to look like, manually edited on Paint. Thanks!
plot_size_p = ggplot (filter(snail_size, food %in% c("C","J","K","L")), aes(x = week, y = mean_size, color = food, shape=infected, linetype=infected)) +
labs(color = "Resource Type",
linetype = "Parasite Status",
shape = "Parasite Status")+
geom_linerange(aes(ymin=mean_size-SEM_size, ymax=mean_size+SEM_size, color=food)) +
geom_point (aes(color = food, shape=infected)) +
geom_line (aes(color = food, linetype=infected))+
scale_color_manual(breaks = c("F","I","H","G","L","K","J","O","N","M","C"),labels = c("100% Pleco Wafers","High N","Med N","Low N","High P","Med P","Low P","High (N+P)","Med (N+P)","Low (N+P)", "Baseline"),values = c("green4", brewer.pal(9, "Reds")[7],brewer.pal(9, "Reds")[6],brewer.pal(9, "Reds")[5],brewer.pal(9, "Blues")[7],brewer.pal(9, "Blues")[6],brewer.pal(9, "Blues")[5],brewer.pal(9, "Purples")[7],brewer.pal(9, "Purples")[6],brewer.pal(9, "Purples")[5], "grey"))+
scale_linetype_manual(breaks=c(0,1), labels=c("Uninfected","Infected"), values=c(1,2))+
scale_shape_manual(breaks=c(0,1), labels=c("Uninfected","Infected"), values=c(19,17))
plot_size_n = ggplot (filter(snail_size, food %in% c("C","G","H","I")), aes(x = week, y = mean_size, color = food, shape=infected, linetype=infected)) +
labs(color = "Resource Type",
linetype = "Parasite Status",
shape = "Parasite Status")+
geom_linerange(aes(ymin=mean_size-SEM_size, ymax=mean_size+SEM_size, color=food)) +
geom_point (aes(color = food, shape=infected)) +
geom_line (aes(color = food, linetype=infected))+
scale_color_manual(breaks = c("F","I","H","G","L","K","J","O","N","M","C"),labels = c("100% Pleco Wafers","High N","Med N","Low N","High P","Med P","Low P","High (N+P)","Med (N+P)","Low (N+P)", "Baseline"),values = c("green4", brewer.pal(9, "Reds")[7],brewer.pal(9, "Reds")[6],brewer.pal(9, "Reds")[5],brewer.pal(9, "Blues")[7],brewer.pal(9, "Blues")[6],brewer.pal(9, "Blues")[5],brewer.pal(9, "Purples")[7],brewer.pal(9, "Purples")[6],brewer.pal(9, "Purples")[5], "grey"))+
scale_linetype_manual(breaks=c(0,1), labels=c("Uninfected","Infected"), values=c(1,2))+
scale_shape_manual(breaks=c(0,1), labels=c("Uninfected","Infected"), values=c(19,17))
plot_size_np = ggplot (filter(snail_size, food %in% c("C","M","N","O")), aes(x = week, y = mean_size, color = food, shape=infected, linetype=infected)) +
labs(color = "Resource Type",
linetype = "Parasite Status",
shape = "Parasite Status")+
geom_point (aes(color = food, shape=infected)) +
geom_line (aes(color = food, linetype=infected))+
scale_color_manual(breaks = c("F","I","H","G","L","K","J","O","N","M","C"),labels = c("100% Pleco Wafers","High N","Med N","Low N","High P","Med P","Low P","High (N+P)","Med (N+P)","Low (N+P)", "Baseline"),values = c("green4", brewer.pal(9, "Reds")[7],brewer.pal(9, "Reds")[6],brewer.pal(9, "Reds")[5],brewer.pal(9, "Blues")[7],brewer.pal(9, "Blues")[6],brewer.pal(9, "Blues")[5],brewer.pal(9, "Purples")[7],brewer.pal(9, "Purples")[6], brewer.pal(9, "Purples")[5], "grey"))+
scale_linetype_manual(breaks=c(0,1), labels=c("Uninfected","Infected"), values=c(1,2))+
scale_shape_manual(breaks=c(0,1), labels=c("Uninfected","Infected"), values=c(19,17))
size_plots = wrap_plots(plot_size_p,plot_size_n,plot_size_np, nrow = 1, ncol = 3)+
plot_layout(guides = "collect")
size_plots
In many cases this is simplest to do with facets. For instance, here I facet by gear
, but color by gear
+am
. That puts two colors into the middle facet:
mtcars |>
mutate(Resource = paste(gear, am)) |>
ggplot(aes(wt, mpg, color = Resource)) +
geom_point(size = 4) +
scale_color_manual(breaks = c("3 0", "4 0", "4 1", "5 1"),
labels = c("Moose", "Bunny", "Rabbit", "Flour"),
values = c("green4", RColorBrewer::brewer.pal(9, "Reds")[7],
RColorBrewer::brewer.pal(9, "Reds")[5], "blue")) +
facet_wrap(~gear)
As @stefan noted in the comments, if we use separate plots with patchwork, we will not see a legend for categories not represented in the data (using ggplot2 >= 3.5.0), unless we add show.legend = TRUE
to the geom in question. Compare the three plots below, the first of which omits that. Its guide doesn't match the other guide so it doesn't get combined:
If we add it, the guides can be combined:
my_col_scale <- scale_color_manual(limits = c("3 0", "4 0", "4 1", "5 1"),
name = "Resource",
labels = c("Moose", "Bunny", "Rabbit", "Flour"),
values = c("green4", RColorBrewer::brewer.pal(9, "Reds")[7],
RColorBrewer::brewer.pal(9, "Reds")[5], "blue"))
mtcars |>
mutate(Resource = paste(gear, am)) -> mtcars2
library(patchwork)
wrap_plots(
ggplot(mtcars2 |> filter(gear == 3), aes(wt, mpg, color = Resource)) +
geom_point(size = 4) + # note missing `show.legend = TRUE`
my_col_scale2,
ggplot(mtcars2 |> filter(gear == 4), aes(wt, mpg, color = Resource)) +
geom_point(size = 4, show.legend = TRUE) +
my_col_scale2,
ggplot(mtcars2 |> filter(gear == 5), aes(wt, mpg, color = Resource)) +
geom_point(size = 4, show.legend = TRUE) +
my_col_scale2
) +
plot_layout(guides = "collect")