Hi,
I've just tried to improve a little helper function for this purpose (*),
arrange <- function(..., nrow=NULL, ncol=NULL, as.table=FALSE,
main=NULL, sub=NULL, plot=TRUE) {
dots <- list(...)
n <- length(dots)
if(is.null(nrow) & is.null(ncol)) { nrow = floor(n/2) ; ncol = ceiling(n/nrow)}
if(is.null(nrow)) { nrow = ceiling(n/ncol)}
if(is.null(ncol)) { ncol = ceiling(n/nrow)}
## NOTE see n2mfrow in grDevices for possible alternative
fg <- frameGrob(layout=grid.layout(nrow,ncol))
ii.p <- 1
for(ii.row in seq(1, nrow)){
ii.table.row <- ii.row
if(as.table) {ii.table.row <- nrow - ii.table.row + 1}
for(ii.col in seq(1, ncol)){
ii.table <- ii.p
if(ii.p > n) break
fg <- placeGrob(fg, ggplotGrob(dots[[ii.table]]),
row=ii.table.row, col=ii.col)
ii.p <- ii.p + 1
}
}
if(!is.null(main) | !is.null(sub)){
g <- frameGrob() # large frame to place title(s) and content
g <- packGrob(g, fg)
if (!is.null(main))
g <- packGrob(g, textGrob(main), side="top")
if (!is.null(sub))
g <- packGrob(g, textGrob(sub), side="bottom")
} else {
g <- fg
}
if(plot) grid.draw(g)
invisible(g)
}
library(ggplot2)
plots = llply(1:5, function(.x) qplot(1:10,rnorm(10),main=paste("plot",.x)))
arrange(plots[[1]],plots[[2]],plots[[3]], nrow=2, as.table=TRUE,
main="test main", sub="subtitle test")
A few improvements that I'd like to make in the future:
- ideally one could mix 'regular' grobs and ggplot2 objects, but I'm
not sure how to deal with a input list of mixed classes
- it is painfully slow, probably because of the use of ggplotGrob()
and grid.pack (the latter could be easily circumvented)
- I guess one would want some options regarding the formatting of the
main and sub titles
ideas are welcome
HTH,
baptiste
(*) this code will eventually appear in the gridextra package at
http://code.google.com/p/gridextra/
--
_____________________________
Baptiste Auguié
School of Physics
University of Exeter
Stocker Road,
Exeter, Devon,
EX4 4QL, UK
http://newton.ex.ac.uk/research/emag
______________________________