Vertical justification and heights in arrangeGrob

301 views Asked by At

I am trying to construct a report with multiple pages. Each page has the same structure, a title that says what hospital is being shown, then a table in the upper half of the page and a plot in the lower half. I am using tableGrob to convert the table to a graphics object and arrangeGrob to put it all into a page. My code looks something like:

library(ggplot2)
library(gridExtra)
library(grid)
library(gtable)

df <- iris[1:10,]
pp <- ggplot(iris, aes(x = Sepal.Length)) + geom_histogram(binwidth = 0.2)

tTitle <- textGrob(paste("Title line 1","\n", "Line 2", "\n", "Line 3"),
                   gp=gpar(fontsize=15))
padding <- unit(3,"line")
tt <- tableGrob(df, rows = NULL, theme = ttheme_minimal())
tt <- gtable_add_rows(tt, heights = grobHeight(tTitle) + padding, pos = 0)
tt <- gtable_add_grob(tt, list(tTitle), t=1, l=1, r=ncol(tt))

pg <- arrangeGrob(tt, pp,
                  nrow=2, as.table=FALSE)

pdf("Demo.pdf", paper = "a4", width = 8.27)
grid.draw(pg)
dev.off()

My problem is that there is lots of space at the top of the page and the bottom of the table is cut off by the plot.

How do I vertically justify the heading and table so that they move up the page, leaving enough space for the plot?

1

There are 1 answers

1
user10630867 On BEST ANSWER

Here's one possibility: query the height of the table (a fixed number dictated by the content), and leave the rest for the plot. Note that paper="a4" introduces its own idiosyncrasies, I'd leave that out.

library(ggplot2)
library(gridExtra)
library(grid)
library(gtable)
library(maggritr)

df <- iris[1:10,]
pp <- ggplot(iris, aes(x = Sepal.Length)) + geom_histogram(binwidth = 0.2)

tTitle <- textGrob(paste("Title line 1","\n", "Line 2", "\n", "Line 3"),
                   gp=gpar(fontsize=15))
padding <- unit(3,"line")

tt <- tableGrob(df, rows = NULL, theme = ttheme_minimal()) %>%
  gtable_add_rows(heights = grobHeight(tTitle) + padding, pos = 0) %>%
  gtable_add_grob(list(tTitle), t=1, l=1, r=ncol(tt)) %>%
  gtable_add_grob(rectGrob(gp=gpar(fill=NA,col="red")),
                  t=1, l=1, r=ncol(tt),b=nrow(tt))

th <- sum(tt$heights)
pg <- arrangeGrob(tt, pp, heights = unit.c(th, unit(1,"npc")-th))

pdf("Demo.pdf", width=21/2.54,height=27.7/2.54)
grid.draw(pg)
dev.off()

Note that with this approach the ggplot will expand to fill the remaining space. If you don't want that, you should assign a fixed height, e.g.

# 10 cm or remaining space on the page if smaller than that
cappedheight = unit.pmin(unit(1,"npc"), unit(10, "cm"))
# wrap plot in a grobTree to assign a viewport (centered in remaining space)
pp1 <- grobTree(ggplotGrob(pp), vp=viewport(height=cappedheight))
pg <- arrangeGrob(tt, pp1, heights = unit.c(th, unit(1,"npc")-th))