Multiple ggplots of different sizes

后端 未结 5 1686
醉酒成梦
醉酒成梦 2020-12-02 12:35

It\'s relatively simple using grid.arrange in the gridExtra package to arrange multiple plots in a matrix, but how can you arrange plots (the ones

相关标签:
5条回答
  • 2020-12-02 13:01

    You can use the same matrix interface as layout with grid.arrange,

    library(gridExtra)
    library(grid)
    gl <- lapply(1:9, function(ii) grobTree(rectGrob(), textGrob(ii)))
    
    grid.arrange(grobs = gl, layout_matrix = rbind(c(1,1,1,2,3),
                                                   c(1,1,1,4,5),
                                                   c(6,7,8,9,9)))
    

    enter image description here

    and the same works for ggplots; note that NA can be used to indicate blank cells. The result is a gtable, compatible with ggsave().

    gl <- replicate(9, ggplot(), FALSE)
    grid.arrange(grobs = gl, layout_matrix = rbind(c(1,1,1,2,3),
                                                   c(1,1,1,4,5),
                                                   c(6,7,8,NA,9)))
    

    0 讨论(0)
  • 2020-12-02 13:11

    An alternative with gtable

    library(gtable)
    
    gl <- lapply(1:9, function(ii) grobTree(textGrob(ii), rectGrob()))
    # gl <- lapply(1:9, function(ii) ggplotGrob(qplot(1,1) + ggtitle(ii)))
    
    gt <- gtable(widths=unit(rep(1,5), "null"),
                 heights=unit(rep(1,3), "null"))
    
    gtable_add_grobs <- gtable_add_grob # alias
    
    gt <- gtable_add_grobs(gt, gl, 
                           l=c(1,4,5,4,5,1,2,3,4),
                           r=c(3,4,5,4,5,1,2,3,5),
                           t=c(1,1,1,2,2,3,3,3,3),
                           b=c(2,1,1,2,2,3,3,3,3))
    grid.newpage()
    grid.draw(gt)
    

    enter image description here

    0 讨论(0)
  • 2020-12-02 13:12

    You can use nested arrangeGrob calls like this example:

    library(ggplot2)
    library(gridExtra)
    
    p <- ggplot(data.frame(x=1, y=1), aes(x,y)) + geom_point()
    
    grid.arrange(
      arrangeGrob(
        p, 
        arrangeGrob(p, p, nrow=2),
        ncol=2 ,widths=c(2,1)),
      arrangeGrob(p, p ,p ,ncol=3, widths=rep(1,3)),
      nrow=2)
    

    Edit:

    gl <- lapply(1:9, function(ii) grobTree(rectGrob(),textGrob(ii)))
    
    grid.arrange(
      arrangeGrob(gl[[1]],
                  do.call(arrangeGrob, c(gl[2:5], ncol=2)),
                  nrow=1,
                  widths=3:2),
      do.call(arrangeGrob, c(gl[6:9], nrow=1, list(widths=c(1,1,1,2)))),
    nrow=2, heights=c(2,1))
    

    enter image description here

    0 讨论(0)
  • 2020-12-02 13:18

    I like the interface provided by the lay_out function (formerly in the wq package) . It takes arguments of the form list(plot, row(s), column(s)). For your example:

    lay_out(list(p1, 1:2, 1:3),
           list(p2, 1, 4),
           list(p3, 1, 5),
           list(p4, 2, 4),
           list(p5, 2, 5),
           list(p6, 3, 1),
           list(p7, 3, 2),
           list(p8, 3, 3),
           list(p9, 3, 4:5))
    

    Which yields:

    enter image description here

    lay_out = function(...) {    
        x <- list(...)
        n <- max(sapply(x, function(x) max(x[[2]])))
        p <- max(sapply(x, function(x) max(x[[3]])))
        grid::pushViewport(grid::viewport(layout = grid::grid.layout(n, p)))    
    
        for (i in seq_len(length(x))) {
            print(x[[i]][[1]], vp = grid::viewport(layout.pos.row = x[[i]][[2]], 
                layout.pos.col = x[[i]][[3]]))
        }
    } 
    

    (Code sourced from a prior version of the wq package, from the commit history on the unofficial Github CRAN mirror.)

    0 讨论(0)
  • 2020-12-02 13:19

    I appreciate all the other answers, but Didzis Elferts's comment on the OP connected to the answer that I found easiest to implement.

    library(ggplot2)
    p1 <- qplot(x=wt,y=mpg,geom="point",main="Scatterplot of wt vs. mpg", data=mtcars)
    p2 <- qplot(x=wt,y=disp,geom="point",main="Scatterplot of wt vs disp", data=mtcars)
    p3 <- qplot(wt,data=mtcars)
    p4 <- qplot(wt,mpg,data=mtcars,geom="boxplot")
    p5 <- qplot(wt,data=mtcars)
    p6 <- qplot(mpg,data=mtcars)
    p7 <- qplot(disp,data=mtcars)
    p8 <- qplot(disp, y=..density.., geom="density", data=mtcars)
    p9 <- qplot(mpg, y=..density.., geom="density", data=mtcars)
    
    vplayout <- function(x, y) viewport(layout.pos.row = x, layout.pos.col = y)
    
    grid.newpage()
    pushViewport(viewport(layout = grid.layout(3, 5))) # 3 rows, 5 columns
    print(p1, vp = vplayout(1:2, 1:3))  # the big plot covers rows 1:2 and cols 1:3
    print(p2, vp = vplayout(1, 4))
    print(p3, vp = vplayout(1, 5))
    print(p4, vp = vplayout(2, 4))
    print(p5, vp = vplayout(2, 5))
    print(p6, vp = vplayout(3, 1))
    print(p7, vp = vplayout(3, 2))
    print(p8, vp = vplayout(3, 3))
    print(p9, vp = vplayout(3, 4:5))
    
    0 讨论(0)
提交回复
热议问题