4

Having some trouble aligning a grid graphics object -- have read all the docs I can find, including the Murrell book, but no success. I think what I'm trying to do is pretty straightforward, so hopefully I'm missing simple.

Here's a reproducible example that will make a PDF of all the air carriers by destination in Hadley's hflights package (mirrors what I am trying to do on a different data set).

require(hflights)
require(gridExtra)
require(Cairo)

make_table <- function(df) {
  p <- tableGrob(
    df
   ,padding.h=unit(.25, "mm")
   ,show.rownames=FALSE
   ,gpar.coretext = gpar(fontsize=8, lineheight=0)
   #this doesn't seem to justify the table
   ,just = c("bottom")
   ,show.box = T
  )
  return(p)
}

dests <- unique(hflights$Dest)

#list to hold the plots
plot_list <- list()

#loop over destinations and make a simple report
for (i in dests) {
  #just this destination
  this_dest <- hflights[hflights$Dest == i, ]

  #the title
  title <- textGrob(label = i, gp = gpar(fontsize=72, fontface = 'bold'))

  #a table of carriers
  carriers <- unique(this_dest$UniqueCarrier)
  carriers <- data.frame(
    carrier=carriers  
  )
  carrier_table <- make_table(carriers)

  #put them together
  p <- arrangeGrob(
    title, carrier_table
   ,nrow=2
  )

  plot_list[[i]] <- p
}


#print the report
Cairo(
  width = 11, height = 8.5 
 ,file = paste('destinations.pdf', sep = ''), type="pdf"
 ,units = "in"
)

  print(plot_list)

dev.off()

I want the entire table produced by tableGrob (in the make_table function) to justify to the top of the grob. Right now it is centered vertically and horizontally inside the grob. Do I need to do that in the call to tableGrob, or is it in the arrangeGrob call? To ask it another way, in case the above is not clear, how can I make the whole table (not the text inside of it) justify to the top/bottom/left/right of its container?

Thanks!

Andrew
  • 9,090
  • 8
  • 46
  • 59
  • You may want to look into the `grid` package itself. Especially the `grid.layout` function is useful to create viewports of a custom size. You trouble with your code stem from `arrangeGrob` which divides the paper into two equally sized viewports. Once you're used to setting up a layout of viewports in `grid` you'll never want to miss it. – SimonG Aug 22 '14 at 22:59
  • @SimonG arrangeGrob is a wrapper around grid.layout, and allows unequal heights. – baptiste Aug 23 '14 at 14:28
  • Really? I didn't realize it also allows to set the alignment. Sorry for the misinformation then! – SimonG Aug 23 '14 at 15:28
  • @SimonG heights and widths can be specified; alignment is another issue. Justification is always rather awkward to handle in grid. – baptiste Aug 23 '14 at 18:57

1 Answers1

6

try this,

enter image description here

library(gridExtra)
justify <- function(x, hjust="center", vjust="center", draw=TRUE){
  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)
  if(draw) grid.draw(x)
  return(x)
}

g <- tableGrob(iris[1:3,1:2])
grid.newpage()
justify(g,"right", "top")
baptiste
  • 75,767
  • 19
  • 198
  • 294