5

I arranged 3 ggplot2 plots into a single figure by using the functionality of package patchwork. I tried to collect the legends and they appeared one next to the other. But still, they are 3 separate legends and I expected a single legend. So how can I merge the legends that contain identical values of the same factor variable into a single legend?

Notes:

  1. And I do not want to remove the legends of separate plots by using, e.g., theme(legend.position = "none") in case some additional factor level appears. I expect patchwork specific solution.
  2. A similar question was answered in Combine and merge legends in ggplot2 with patchwork but the data was continuous. And in my case, I have categorical data.

The code:

library(ggplot2)
library(patchwork)

iris_1 <-
  ggplot(iris, aes(x = Sepal.Length, fill = Species, color = Species)) +
  geom_density(alpha = 0.3, adjust = 1.5)

iris_2 <-
  ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, color = Species)) +
  geom_point()

iris_3 <-
  ggplot(iris, aes(x = Species, y = Sepal.Width, fill = Species)) +
  geom_boxplot()


(iris_1 + iris_2 + iris_3) + plot_layout(guides = "collect")

Created on 2020-10-14 by the reprex package (v0.3.0)


Update

I tried using the same aesthetic mappings (fill = Species and color = Species) as it was proposed in the comments below but it had no effect:

library(tidyverse)
library(patchwork)

iris_1 <-
  ggplot(iris, aes(x = Sepal.Length, color = Species, fill = Species)) +
  geom_density(alpha = 0.3, adjust = 1.5)

iris_2 <-
  ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, color = Species, fill = Species)) +
  geom_point()

iris_3 <-
  ggplot(iris, aes(x = Species, y = Sepal.Width, color = Species, fill = Species)) +
  geom_boxplot(color = "black")

(iris_1 + iris_2 + iris_3) + plot_layout(guides = "collect")

Created on 2020-10-14 by the reprex package (v0.3.0)

GegznaV
  • 4,938
  • 4
  • 23
  • 43
  • 1
    This is because you have set inconsistent fill and colour values between the plots - if you add fill = Species and colour = Species to all plots, patchwork should be able to collect the legends. – mlcyo Oct 13 '20 at 23:16
  • @mlcyo, it didn't work for me. Does it work for you? (See the updated question). Is it the case that I did shomething different than you suggested? – GegznaV Oct 14 '20 at 09:16

1 Answers1

3

Unfortunately setting the same aes is only one condition. patchwork will merge legends only if they are identical. Therefore we have to ensure that the legends are the same for each plot. To this end I add a guides layer which makes the look of each legend the same by setting color, shape, size and alpha. Additionally we have to choose the same glyph for each geom using argument key_glyph. After these adjustments the three legends get merged into one.

library(ggplot2)
library(patchwork)

g <- guides(fill = guide_legend(override.aes = list(color = scales::hue_pal()(3),
                                                    shape = c(16, 16, 16), 
                                                    size = c(1, 1, 1),
                                                    alpha = c(1, 1, 1)),))

iris_1 <-
  ggplot(iris, aes(x = Sepal.Length)) +
  geom_density(aes(fill = Species, color = Species), key_glyph = "point", alpha = 0.3, adjust = 1.5) +
  g

iris_2 <-
  ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width)) +
  geom_point(aes(fill = Species, color = Species), key_glyph = "point") +
  g

iris_3 <-
  ggplot(iris, aes(x = Species, y = Sepal.Width)) +
  geom_boxplot(aes(fill = Species, color = Species), key_glyph = "point") +
  scale_color_manual(values = c("black", "black", "black")) +
  g


(iris_1 + iris_2 + iris_3) + plot_layout(guides = "collect")

stefan
  • 90,330
  • 6
  • 25
  • 51