I am trying to add y axis labels to my figure (a compilation of 6 figures in a 2x3 arrangement. The top 3 figures are part of one group, and the bottom 3 are part of another so I'd like to add two separate y axis labels at the start of each row. I am using the ggarrange function in {ggpubr}.
The image below is what I would like to have (i.e. the additional "Abundance" and "Presence/Absence" labels.
Below is the code I am using:
fig <- ggarrange(p1, p2 p3, p4, p5, p6, ncol=3, nrow=2, common.legend=FALSE, align="v", labels=c("A)","B)","C)","D)","E)","F)"))
Thank you in advance for your suggestions!
CodePudding user response:
It seems the thing you're trying to do is not super easy to do natively with ggpubr::ggarrange
. I usually prefer {patchwork} but didn't find an easy solution there either. However, there is a feature request on github that contains some code which I was able to turn into a solution here.
library(tidyverse)
library(patchwork)
# borrowed from: https://github.com/thomasp85/patchwork/issues/43
add_global_label <- function(pwobj, Xlab = NULL, Ylab = NULL, Xgap = 0.03, Ygap = 0.03, ...) {
ylabgrob <- patchwork::plot_spacer()
if (!is.null(Ylab)) {
ylabgrob <- ggplot()
geom_text(aes(x = .5, y = .5), label = Ylab, angle = 90, ...)
theme_void()
}
if (!is.null(Xlab)) {
xlabgrob <- ggplot()
geom_text(aes(x = .5, y = .5), label = Xlab, ...)
theme_void()
}
if (!is.null(Ylab) & is.null(Xlab)) {
return((ylabgrob patchworkGrob(pwobj))
patchwork::plot_layout(widths = 100 * c(Ygap, 1 - Ygap)))
}
if (is.null(Ylab) & !is.null(Xlab)) {
return((ylabgrob pwobj)
(xlabgrob)
patchwork::plot_layout(heights = 100 * c(1 - Xgap, Xgap),
widths = c(0, 100),
design = "
AB
CC
"
))
}
if (!is.null(Ylab) & !is.null(Xlab)) {
return((ylabgrob pwobj)
(xlabgrob)
patchwork::plot_layout(heights = 100 * c(1 - Xgap, Xgap),
widths = 100 * c(Ygap, 1 - Ygap),
design = "
AB
CC
"
))
}
return(pwobj)
}
p <- mtcars %>%
ggplot(aes(disp, mpg))
geom_point(aes(color = factor(cyl)))
theme_classic()
top <- ((p p p)
plot_annotation(tag_levels = list(LETTERS[1:3]), tag_suffix = ")")) %>%
add_global_label(Ylab = "Top Row")
bottom <- ((p p p)
plot_annotation(tag_levels = list(LETTERS[4:6]), tag_suffix = ")")) %>%
add_global_label(Ylab = "Bottom Row")
top/bottom
Created on 2022-04-04 by the reprex package (v2.0.1)
CodePudding user response:
The {cowplot} package has a native solution to this problem, but it will probably take a little more fiddling to get the spacing right to avoid the label overlapping the y
axis title.
library(tidyverse)
library(cowplot)
# make basic plot
p <- mtcars %>%
ggplot(aes(disp, mpg))
geom_point(aes(color = factor(cyl)))
theme_classic()
# compose top row of plots with labels
t <- plot_grid(
p, p, p,
labels = paste0(LETTERS[1:3], ")"),
label_size = 12,
nrow = 1) %>%
ggdraw()
draw_label("Top Row", size = 16, angle = 90, x = 0.01, y = 0.5)
# compose bottom row of plots with labels
b <- plot_grid(
p, p, p,
labels = paste0(LETTERS[4:6], ")"),
label_size = 12,
nrow = 1) %>%
ggdraw()
draw_label("Bottom Row", size = 16, angle = 90, x = 0.01, y = 0.5)
# compose overall layout
plot_grid(t, b, nrow = 2)
Created on 2022-04-04 by the reprex package (v2.0.1)