How can I arrange an arbitrary number of ggplots using grid.arrange?

后端 未结 3 1875
死守一世寂寞
死守一世寂寞 2020-11-28 01:31

This is cross-posted on the ggplot2 google group

My situation is that I\'m working on a function that outputs an arbitrary number of plots

相关标签:
3条回答
  • 2020-11-28 02:17

    You're ALMOST there! The problem is that do.call expects your args to be in a named list object. You've put them in the list, but as character strings, not named list items.

    I think this should work:

    args.list <- c(plot.list, 2,2)
    names(args.list) <- c("x", "y", "z", "nrow", "ncol")
    

    as Ben and Joshua pointed out in the comments, I could have assigned names when I created the list:

    args.list <- c(plot.list,list(nrow=2,ncol=2))
    

    or

    args.list <- list(x=x, y=y, z=x, nrow=2, ncol=2)
    
    0 讨论(0)
  • 2020-11-28 02:24

    I'm answering a bit late, but stumbled on a solution at the R Graphics Cookbook that does something very similar using a custom function called multiplot. Perhaps it will help others who find this question. I'm also adding the answer as the solution may be newer than the other answers to this question.

    Multiple graphs on one page (ggplot2)

    Here's the current function, though please use the above link, as the author noted that it's been updated for ggplot2 0.9.3, which indicates it may change again.

    # Multiple plot function
    #
    # ggplot objects can be passed in ..., or to plotlist (as a list of ggplot objects)
    # - cols:   Number of columns in layout
    # - layout: A matrix specifying the layout. If present, 'cols' is ignored.
    #
    # If the layout is something like matrix(c(1,2,3,3), nrow=2, byrow=TRUE),
    # then plot 1 will go in the upper left, 2 will go in the upper right, and
    # 3 will go all the way across the bottom.
    #
    multiplot <- function(..., plotlist=NULL, file, cols=1, layout=NULL) {
      require(grid)
    
      # Make a list from the ... arguments and plotlist
      plots <- c(list(...), plotlist)
    
      numPlots = length(plots)
    
      # If layout is NULL, then use 'cols' to determine layout
      if (is.null(layout)) {
        # Make the panel
        # ncol: Number of columns of plots
        # nrow: Number of rows needed, calculated from # of cols
        layout <- matrix(seq(1, cols * ceiling(numPlots/cols)),
                        ncol = cols, nrow = ceiling(numPlots/cols))
      }
    
     if (numPlots==1) {
        print(plots[[1]])
    
      } else {
        # Set up the page
        grid.newpage()
        pushViewport(viewport(layout = grid.layout(nrow(layout), ncol(layout))))
    
        # Make each plot, in the correct location
        for (i in 1:numPlots) {
          # Get the i,j matrix positions of the regions that contain this subplot
          matchidx <- as.data.frame(which(layout == i, arr.ind = TRUE))
    
          print(plots[[i]], vp = viewport(layout.pos.row = matchidx$row,
                                          layout.pos.col = matchidx$col))
        }
      }
    }
    

    One creates plot objects:

    p1 <- ggplot(...)
    p2 <- ggplot(...)
    # etc.
    

    And then passes them to multiplot:

    multiplot(p1, p2, ..., cols = n)
    
    0 讨论(0)
  • 2020-11-28 02:28

    Try this,

    require(ggplot2)
    require(gridExtra)
    plots <- lapply(1:11, function(.x) qplot(1:10,rnorm(10), main=paste("plot",.x)))
    
    params <- list(nrow=2, ncol=2)
    
    n <- with(params, nrow*ncol)
    ## add one page if division is not complete
    pages <- length(plots) %/% n + as.logical(length(plots) %% n)
    
    groups <- split(seq_along(plots), 
      gl(pages, n, length(plots)))
    
    pl <-
      lapply(names(groups), function(g)
             {
               do.call(arrangeGrob, c(plots[groups[[g]]], params, 
                                      list(main=paste("page", g, "of", pages))))
             })
    
    class(pl) <- c("arrangelist", "ggplot", class(pl))
    print.arrangelist = function(x, ...) lapply(x, function(.x) {
      if(dev.interactive()) dev.new() else grid.newpage()
       grid.draw(.x)
       }, ...)
    
    ## interactive use; open new devices
    pl
    
    ## non-interactive use, multipage pdf
    ggsave("multipage.pdf", pl)
    
    0 讨论(0)
提交回复
热议问题