Align ggplot2 plots vertically
Here's an example to align more basic grobs,
library(ggplot2)library(grid)library(gtable)p <- qplot(1,1)g <- ggplotGrob(p)panel_id <- g$layout[g$layout$name == "panel",c("t","l")]g <- gtable_add_cols(g, unit(1,"cm"))g <- gtable_add_grob(g, rectGrob(gp=gpar(fill="red")), t = panel_id$t, l = ncol(g))g <- gtable_add_rows(g, unit(1,"in"), 0)g <- gtable_add_grob(g, rectGrob(gp=gpar(fill="blue")), t = 1, l = panel_id$l)grid.newpage()grid.draw(g)
and with your grobs
The answer from @baptiste helped me get a better understanding of the gtable structure and how to modify it. Below I post just my modified variant as code snippet for (my own) reuse.
It is using find_panel()
to get the panel extent, and pipes %>%
the modifications directly into grid.draw
. The piping considerably simplified playing around with the gtable_*
functions, as it allows to easily uncomment single lines and check the effect on the final plot.
library(ggplot2)library(grid)library(gtable)library(dplyr)p <- ggplot(tribble(~x,~y,~a,~b, 1, 1, "a1","b1", 1, 1, "a2","b1", 1, 1, "a2","b2"), aes(x=x,y=y)) + geom_point() + facet_grid(vars(a),vars(b))g <- ggplotGrob(p)panels_extent <- g %>% find_panel()g %>% # Add red box to the very right, by appending a column and then filling it gtable_add_cols(widths = unit(1,"cm"), pos = -1) %>% gtable_add_grob(rectGrob(gp=gpar(fill="red")), t = panels_extent$t, b = panels_extent$b, l = -1, r = -1) %>% # Add green box to the top, by prepending a row and then filling it # Note the green box extends horizontally over the first panel as well # as the space in between. gtable_add_rows(heights = unit(1,"cm"), pos = 0) %>% gtable_add_grob(rectGrob(gp=gpar(fill="green")), t = 1, b = 1, l = panels_extent$l, r = panels_extent$l+1) %>% {grid.newpage();grid.draw(.)}