Open GegznaV opened 4 years ago
Do you want to merge the legends like below?
library(tidyverse)
suppressPackageStartupMessages(library(ggpubr))
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 = Sepal.Width)) +
geom_point()
iris_3 <-
ggplot(iris, aes(x = Species, y = Sepal.Width, fill = fct_rev(Species))) +
geom_boxplot()
# Merging legends
legend_1 <- get_legend(iris_1)
legend_2 <- get_legend(iris_2)
legend_3 <- get_legend(iris_3)
legends <- ggarrange(legend_1, legend_2, legend_3, nrow=3)
# Combining plots
rm_legend <- function(p){p + theme(legend.position = "none")}
plots <- ggarrange(rm_legend(iris_1), rm_legend(iris_2), rm_legend(iris_3), nrow = 1)
# plots + merged legends
ggarrange(plots, legends, widths = c(0.75, 0.25))
Created on 2020-10-14 by the reprex package (v0.3.0.9001)
In this particular case, where a new legend misrepresents data, separate legends would be a more correct solution.
But in case, when the legends can be merged, a single legend should be preferred. E.g., I like this output:
library(tidyverse)
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()
ggpubr::ggarrange(iris_1, iris_2, iris_3, nrow = 1, common.legend = TRUE)
Created on 2020-10-14 by the reprex package (v0.3.0)
Even more challenging is the situation, where I expect some legends to be merged and some – not. E.g., here I expect 2 legends (one for discrete colors and the other one for continuous colors) but now the legend for continuous colors is missing:
library(tidyverse)
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 = Sepal.Width)) +
geom_point()
iris_3 <-
ggplot(iris, aes(x = Species, y = Sepal.Width, fill = Species)) +
geom_boxplot()
ggpubr::ggarrange(iris_1, iris_2, iris_3, nrow = 1, common.legend = TRUE)
Created on 2020-10-14 by the reprex package (v0.3.0)
OK, I can see the issue know; you want to keep the first and the second legends in the arranged plots.
The current behavior of the option common.legend
is to keep only the legend of the first plot. A possible improvement would be to be able to specify something like common.legend = c(1, 2)
, so that the legends of the first and the second plots are kept.
I thought that the function should check and merge the values in several legends to create a single common legend. But now I see that the user decides if all plots can be represented by a legend of the first plot and common.legend = TRUE
actually means discard all the legends but the first one
.
In no checking is performed and the legends are not actually merged, then common.legend = c(1, 2)
would be a nice alternative that enables to keep the legends of interest.
I believe that a first quick step to resolve this issue would be to properly document the current behaviour. In version 0.4.0, the argument's description is as follows:
common.legend
: logical value. Default is FALSE. If TRUE, a common unique legend will be created for arranged plots.
It really does make it sound like a common legend is created to accurately describe all plots included.
This issue is particularly problematic for combined plots that share the same geometry and colour scale, for example:
library(ggplot2)
library(palmerpenguins)
peng_simple <- ggplot(penguins,
aes(x = bill_length_mm,
y = bill_depth_mm,
colour = bill_depth_mm)) +
geom_point()
# same, but bill depth is multiplied by 3
peng_triple <-ggplot(penguins,
aes(x = bill_length_mm,
y = bill_depth_mm * 3,
colour = bill_depth_mm * 3)) +
geom_point()
ggpubr::ggarrange(peng_simple, peng_triple,
nrow = 1, common.legend = TRUE)
Created on 2022-02-16 by the reprex package (v2.0.1)
I believe that a first quick step to resolve this issue would be to properly document the current behaviour. In version 0.4.0, the argument's description is as follows:
common.legend
: logical value. Default is FALSE. If TRUE, a common unique legend will be created for arranged plots.It really does make it sound like a common legend is created to accurately describe all plots included.
Even more so, it is not true that a "common unique legend" is created because only the first legend is chosen. In my case, I have missing data (NA) for one group in the first plot, but this group is present in all subsequent plots. With common.legend
and the current description I expected that all unique groups would be represented instead of only those of the first plot.
Following.
Any updates on this? Is "common.legend" still using the legend of the first plot rather than a merged legend?
Any updates on this? Is "common.legend" still using the legend of the first plot rather than a merged legend?
I think you can use "legend.grob" to specify which plot to use for the legend.
anyone found a good workaround for this? I have two plots that have the same continuous color scale, and the legend i get using ggarrange is just totally inaccurate for one of them
Function
ggarrange(common.legend = TRUE)
returns a misleading legend. Note the reversed order of factor levels iniris_1
andiris_3
and continuous legend iniris_2
.Created on 2020-10-14 by the reprex package (v0.3.0)