library(gtable)
## Loading required package: grid


gtable_arrange <- function(..., grobs=list(), as.table=TRUE){

  dots <- list(...)
  params <- c("nrow", "ncol", "widths", "heights",
              "respect", "just", "z") # TODO currently ignored

  layout.call <- intersect(names(dots), params)
  params.layout <- dots[layout.call]

  if(is.null(names(dots)))
    not.grobnames <- FALSE else
      not.grobnames <- names(dots) %in% layout.call

  if(!length(grobs))
  grobs <- dots[! not.grobnames ]

  ## figure out the layout
  n <- length(grobs)
  nm <- n2mfrow(n)

  if(is.null(params.layout$nrow) & is.null(params.layout$ncol)) 
  {
    params.layout$nrow = nm[1]
    params.layout$ncol = nm[2]
  }
  if(is.null(params.layout$nrow))
    params.layout$nrow = ceiling(n/params.layout$ncol)
  if(is.null(params.layout$ncol))
    params.layout$ncol = ceiling(n/params.layout$nrow)

  if(is.null(params.layout$widths))
    params.layout$widths <- unit(rep(1, params.layout$ncol), "null")
  if(is.null(params.layout$heights))
    params.layout$heights <- unit(rep(1,params.layout$nrow), "null")

  positions <- expand.grid(row = seq_len(params.layout$nrow), 
                           col = seq_len(params.layout$ncol))
  if(as.table) # fill table by rows
    positions <- positions[order(positions$row),]

  positions <- positions[seq_along(grobs), ] # n might be < ncol*nrow

  ## build the gtable, similar steps to gtable_matrix

  gt <- gtable(name="table")
  gt <- gtable_add_cols(gt, params.layout$widths)
  gt <- gtable_add_rows(gt, params.layout$heights)
  gt <- gtable_add_grobs(gt, grobs, t = positions$row, 
                            l = positions$col)


  grid.newpage()
  grid.draw(gt)
  gt
}

gs <- lapply(1:7, function(ii) grobTree(rectGrob(gp=gpar(fill=ii, alpha=0.5)),
                                        textGrob(ii)))
gtable_arrange(ncol=3, grobs=gs)

plot of chunk unnamed-chunk-1

## TableGrob (3 x 3) "table": 7 grobs
##   z     cells  name                 grob
## 1 1 (1-1,1-1) table  gTree[GRID.gTree.1]
## 2 2 (1-1,2-2) table  gTree[GRID.gTree.4]
## 3 3 (1-1,3-3) table  gTree[GRID.gTree.7]
## 4 4 (2-2,1-1) table gTree[GRID.gTree.10]
## 5 5 (2-2,2-2) table gTree[GRID.gTree.13]
## 6 6 (2-2,3-3) table gTree[GRID.gTree.16]
## 7 7 (3-3,1-1) table gTree[GRID.gTree.19]
g <- gtable_arrange(ncol=3, grobs=gs, as.table=FALSE)

plot of chunk unnamed-chunk-1


gtable_add_grobs <- gtable_add_grob # alias
g <- gtable_add_rows(g, unit(1,"line"), pos=0)
g <- gtable_add_grobs(g, lapply(paste("main #", 1:3), textGrob),
                      t=1, l=1:3)
grid.newpage()
grid.draw(g)

plot of chunk unnamed-chunk-1


require(ggplot2)
## Loading required package: ggplot2
grid.newpage()
g <- gtable_arrange(ncol=3, grobs=gs)
g <- gtable_add_grobs(g, textGrob("Annotation"), t=3,l=2,r=3)
grid.draw(g)

plot of chunk unnamed-chunk-1