0

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.

MAPK
  • 5,635
  • 4
  • 37
  • 88
  • 1
    @akrun I mean to say arrow indicating Y pointing up and down, and X pointing sideways – MAPK Sep 05 '19 at 20:01
  • I have couple hacky solutions but would you first provide us with a more general example (instead of one df with the same x and y, something closer to your actual problem which would result in different plots and axis ranges). – M-- Sep 05 '19 at 20:27
  • @M-- I have updated the data. – MAPK Sep 05 '19 at 20:42
  • Where would the lines be, bottom and left axis lines? And on all plots? – camille Sep 05 '19 at 21:21
  • @camille One line on the left and one at the bottom. Not on all plots. – MAPK Sep 05 '19 at 21:26

1 Answers1

2

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

Cole
  • 11,130
  • 1
  • 9
  • 24
  • Thanks, but how do you add a line/arrow to cover the axes? – MAPK Sep 05 '19 at 22:21
  • Could you annotate yours? I am unsure about these lines / arrows. – Cole Sep 05 '19 at 22:22
  • I could add this line in Inkscape, but Just wanted to try in R. The line(wtih arrow) is just to show it spans Y on the left of the figure and X at the bottom of the figure. Just one long line on the left and one long line at the bottom – MAPK Sep 05 '19 at 22:26
  • 1
    @MAPK, see edit. It's not perfect but it results in arrows. – Cole Sep 06 '19 at 02:13