Achal Neupane
Achal Neupane

Reputation: 5719

Add common axis titles with lines/arrows for multiple plots in ggplot

I have my dummy data and plot as:

library(ggpubr)
d1 <- data.frame(x = c(5, 2, 3), y = c(7, 5, 6))
d2 <- data.frame(x = c(3, 2, 1), y = c(6, 5, 4))
d3 <- data.frame(x = c(5, 6, 3), y = c(8, 6, 6))
d4 <- data.frame(x = c(3, 8, 1), y = c(6, 3, 5))
bp <- list(d1, d2, d3, d4)
bp

cbp <- vector("list", length = 4)
for (i in 1:4) {
  cbp[[i]] <- ggplot(bp[[i]], aes(x= x, y = y))+geom_point()
}

ggarrange(plotlist = cbp, labels = c("A", "B", "C", "D"), ncol = 2, nrow = 2)

enter image description here

Instead of X and Y axis titles in all four plots, I would like to have a common X and Y title with lines for Y pointing up and down, and for X, pointing sideways. Is it possible to make such change in this plot? Please note these ggobjects come from loop, so facet_grid won't work for me.

Upvotes: 0

Views: 1220

Answers (1)

Cole
Cole

Reputation: 11255

While OP mentions that facet_grid cannot be used because of a loop, there's nothing special about the loop that would prevent it from being used:

library(data.table)
dt <- rbindlist(bp, id = 'dt_list')

p <- ggplot(dt, aes(x = x, y = y))+
  geom_point()+
  facet_wrap(vars(dt_list), scales = 'free', strip.position = 'left')

p+theme_classic()

ggplot2 facet_wrap Or you could strip the facet labels and annotate it:

caption_helper <- dt[, .(y = max(y), x= min(x)), by = dt_list]

p+theme(strip.text = element_blank(), strip.background = element_blank())+
  geom_text(data = caption_helper, aes(x = x, y = y, label = dt_list), fontface = 'bold')

ggplot2 manual caption

Finally, to add the line and arrows, here is a somewhat manual way to do it. As I resize the plot, the lines also mess up:

p+theme(strip.text = element_blank(), strip.background = element_blank())+
  geom_text(data = caption_helper, aes(x = x, y = y, label = dt_list), fontface = 'bold')

library(grid)
pushViewport(viewport())
grid.lines(x = unit(c(0.1,0.95), 'npc'),
           y = unit(0.036, 'npc'),
           gp = gpar(col = "black"),
           arrow = arrow(angle = 30, length = unit(0.25, "inches"),
                         ends = "last", type = "open"))

grid.lines(x = 0.03,
           y = c(0.1,0.95),
           gp = gpar(col = "black"),
           arrow = arrow(angle = 30, length = unit(0.25, "inches"),
                         ends = "last", type = "open"))

popViewport()

ggplot line below axis

Upvotes: 2

Related Questions