Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to perfectly align an unequal number of plots (ggplot2,gridExtra)

I would like to perfectly align these plots :

unaligned plots

Here is the R code :

library(tidyverse)
library(gridExtra)
groupes <- tribble(~type, ~group, ~prof, ~var,
                   1,1,1,12,
                   1,1,2,-24,
                   1,2,1,-11,
                   1,2,2,7,
                   2,1,1,10,
                   2,1,2,5,
                   2,2,1,-25,
                   2,2,2,2,
                   2,3,1,10,
                   2,3,2,3,
                   3,1,1,10,
                   3,1,2,-5,
                   3,2,1,25,
                   3,2,2,2,
                   3,3,1,-10,
                   3,3,2,3,
                   3,4,1,25,
                   3,4,2,-18)


hlay <- rbind(c(1,2,3),
              c(1,2,3),
              c(NA,2,3),
              c(NA,NA,3))

p1 <-  groupes %>% filter(type==1) %>% ggplot(aes(prof,var)) + geom_col() + facet_wrap(~group,ncol=1) +
  coord_cartesian(ylim=c(-25,25)) +
  labs(title="type 1",x="",y="")
p2 <-  groupes %>% filter(type==2) %>% ggplot(aes(prof,var)) + geom_col() + facet_wrap(~group,ncol=1) +
  coord_cartesian(ylim=c(-25,25)) +
  labs(title="type 2",x="",y="")
p3 <-  groupes %>% filter(type==3) %>% ggplot(aes(prof,var)) + geom_col() + facet_wrap(~group,ncol=1) +
  coord_cartesian(ylim=c(-25,25)) +
  labs(title="type 3",x="",y="")
grid.arrange(p1,p2,p3, layout_matrix=hlay)

I may succeed to produce a better alignment by adding heights=c(1.3,1,1,1) into grid.arrange but that is not a perfect solution. Another solution would be not to take into account the space taken by the labels, but I do not know how to do that.

like image 226
user1788720 Avatar asked Mar 10 '18 08:03

user1788720


1 Answers

it's probably more manageable if you can set an absolute panel size (and size the device accordingly).

justify <- function(x, hjust="center", vjust="center"){
  w <- sum(x$widths)
  h <- sum(x$heights)
  xj <- switch(hjust,
               center = 0.5,
               left = 0.5*w,
               right=unit(1,"npc") - 0.5*w)
  yj <- switch(vjust,
               center = 0.5,
               bottom = 0.5*h,
               top=unit(1,"npc") - 0.5*h)
  x$vp <- viewport(x=xj, y=yj)
  return(x)
}

library(grid)
gl <- lapply(list(p1,p2,p3),egg::set_panel_size, height=unit(1,"in"))
gl <- lapply(gl, justify, vjust="top")
gridExtra::grid.arrange(grobs=gl, nrow=1)

enter image description here

like image 88
user9471246 Avatar answered Oct 04 '22 02:10

user9471246