Aligning pairs of tableGrobs with uneven numbers of rows within and between subplots

56 Views Asked by At

I would like to make a figure containing several subplots. Some of these subplots I would like to be tables. However, the problem I have been facing is that I cannot get the tables to align with each other. I would like each table to be aligned to the "top" of each subplot.

I have tried using the following code:

## Reprex 
library(ggplot2)
library(gridExtra)
library(cowplot)
library(ggpubr)

#Data

dataA <- data.frame("A" = rep("A", 3),"B" = rep("B", 3),"C" = rep("C", 3))
dataB <- data.frame("A" = rep("A", 4),"B" = rep("B", 4),"C" = rep("C", 4))
dataC <- data.frame("A" = rep("A", 5),"B" = rep("B", 5),"C" = rep("C", 5))
dataD <- data.frame("A" = rep("A", 3),"B" = rep("B", 3),"C" = rep("C", 3))

#Convert to Grob


fig_subplotA <- arrangeGrob(tableGrob(dataA, rows = NULL),
                     tableGrob(dataB, rows = NULL), ncol = 2)

fig_subplotB <- arrangeGrob(tableGrob(dataC, rows = NULL), 
                     tableGrob(dataD, rows = NULL), ncol = 2)


# Make final plot 

g <- list(fig_subplotA, fig_subplotB)

p.final <- arrangeGrob(grobs=g, ncol = 2)

p <- as_ggplot(p.final)+
        draw_plot_label(label = c("a", "b"), x = c(0, 0.5))
p

#Export 

ggsave(filename = "FigureExample.png", p, width = 4, height = 3)

The output looks like:

Output

and I would like something like:

Goal

Thanks a lot for any input!

1

There are 1 best solutions below

0
Allan Cameron On BEST ANSWER

As far as I can tell, there is no vertical justification method for tableGrob, so this requires calculating the correct viewport position based on the grob heights, which is a bit long-winded, and probably best wrapped in a function:

justify <- function(x, just = 1) {
  height <- as.numeric(grid::convertHeight(sum(x$heights), 'npc'))
  x$vp <- grid::viewport(y = just + height * (0.5 - just))
  x
}

This allows:

A <- tableGrob(dataA, rows = NULL)
B <- tableGrob(dataB, rows = NULL) 
subplotA <- arrangeGrob(justify(A), justify(B), ncol = 2)

C <- tableGrob(dataC, rows = NULL)
D <- tableGrob(dataD, rows = NULL) 
subplotB <- arrangeGrob(justify(C), justify(D), ncol = 2)

arrangeGrob(grobs = list(subplotA, subplotB), ncol = 2) |>
  as_ggplot() +
  draw_plot_label(label = c("a", "b"), x = c(0, 0.5))

enter image description here