Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用grid.arrange排列任意数量的GGPlot?_R_Ggplot2 - Fatal编程技术网

如何使用grid.arrange排列任意数量的GGPlot?

如何使用grid.arrange排列任意数量的GGPlot?,r,ggplot2,R,Ggplot2,这是在ggplot2谷歌群上交叉发布的 我的情况是,输出任意数量的绘图(取决于用户提供的输入数据)。该函数返回一个n个图的列表,我想以2x2的形式展示这些图。我正在努力解决以下同时出现的问题: 我如何允许将灵活性交给任意(n)个绘图 我怎样才能指定我希望它们的布局为2 x 2 我当前的策略使用grid。从gridExtra包中排列。它可能不是最优的,特别是因为,这是关键,它完全不起作用。下面是我的注释示例代码,尝试了三个绘图: library(ggplot2) library(gridExtra

这是在ggplot2谷歌群上交叉发布的

我的情况是,输出任意数量的绘图(取决于用户提供的输入数据)。该函数返回一个n个图的列表,我想以2x2的形式展示这些图。我正在努力解决以下同时出现的问题:

  • 我如何允许将灵活性交给任意(n)个绘图
  • 我怎样才能指定我希望它们的布局为2 x 2
  • 我当前的策略使用
    grid。从
    gridExtra
    包中排列
    。它可能不是最优的,特别是因为,这是关键,它完全不起作用。下面是我的注释示例代码,尝试了三个绘图:

    library(ggplot2)
    library(gridExtra)
    
    x <- qplot(mpg, disp, data = mtcars)
    y <- qplot(hp, wt, data = mtcars)
    z <- qplot(qsec, wt, data = mtcars)
    
    # A normal, plain-jane call to grid.arrange is fine for displaying all my plots
    grid.arrange(x, y, z)
    
    # But, for my purposes, I need a 2 x 2 layout. So the command below works acceptably.
    grid.arrange(x, y, z, nrow = 2, ncol = 2)
    
    # The problem is that the function I'm developing outputs a LIST of an arbitrary
    # number plots, and I'd like to be able to plot every plot in the list on a 2 x 2
    # laid-out page. I can at least plot a list of plots by constructing a do.call()
    # expression, below. (Note: it totally even surprises me that this do.call expression
    # DOES work. I'm astounded.)
    plot.list <- list(x, y, z)
    do.call(grid.arrange, plot.list)
    
    # But now I need 2 x 2 pages. No problem, right? Since do.call() is taking a list of
    # arguments, I'll just add my grid.layout arguments to the list. Since grid.arrange is
    # supposed to pass layout arguments along to grid.layout anyway, this should work.
    args.list <- c(plot.list, "nrow = 2", "ncol = 2")
    
    # Except that the line below is going to fail, producing an "input must be grobs!"
    # error
    do.call(grid.arrange, args.list)
    
    库(ggplot2)
    图书馆(gridExtra)
    
    你就快到了!问题是,
    do.call
    希望您的参数位于命名的
    列表
    对象中。您已将它们放在列表中,但作为字符串,而不是命名的列表项

    我认为这应该奏效:

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

    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)
    
    require(ggplot2)
    需要(额外)
    
    plots我回答得有点晚,但在R Graphics Cookbook上偶然发现了一个解决方案,它使用一个名为
    multiplot
    的自定义函数做了一些非常类似的事情。也许它会帮助其他发现这个问题的人。我还添加了答案,因为解决方案可能比这个问题的其他答案更新

    这是当前函数,但请使用上面的链接,因为作者注意到它已针对ggplot2 0.9.3进行了更新,这表明它可能再次更改

    # 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))
        }
      }
    }
    

    我更改了几次代码。很抱歉编辑了。现在有意义了吗?当我早些时候说它们是矢量时,我说错了。很抱歉。您可以在创建列表时命名args:
    args.list不完全正确。你的长度合适。您的列表结构与京东的列表结构不同。使用str()和names()。您的所有列表元素都未命名,因此要使
    do.call
    成功,需要精确的位置匹配。@JD Long;我完全同意。即使不能防止所有的错误,如果使用命名参数,仍然可以获得更好的错误消息和
    traceback()
    信息;由于
    grid.arrange()
    的第一个参数是
    位置匹配可能不相关。每个输入必须是一个网格对象(带或不带名称),一个用于
    网格布局的命名参数,或者一个用于其余参数的命名参数。这是一个非常好的问题。我将用这个例子来说明如何写出一个好的SO[r]问题,尤其是“谦逊地蜷缩”部分——一点也不像一个好的卑躬屈膝:)@JD和@Ben——我很荣幸,伙计们。真诚地我真的很感谢gridExtra的help.version>=0.9提供了marrangeGrob,每当nrow*ncolggsave(“multipage.pdf”,do.call(marrangeGrob,c(plots,list(nrow=2,ncol=2)))时,marrangeGrob都能自动完成这一切。
    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)
    
    # 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))
        }
      }
    }
    
    p1 <- ggplot(...)
    p2 <- ggplot(...)
    # etc.
    
    multiplot(p1, p2, ..., cols = n)