首页 文章

左对齐两个图形边(ggplot)

提问于
浏览
97

我正在使用ggplot并且有两个图表,我希望彼此叠加显示 . 我使用gridExtra中的 grid.arrange 来堆叠它们 . 问题是,无论轴标签如何,我都希望图形的左边缘与右边缘对齐 . (问题出现是因为一个图的标签很短而另一个图很长) .

The Question:
我怎样才能做到这一点?我没有和grid.arrange结婚,但ggplot2是必须的 .

What I've tried:
我尝试使用宽度和高度以及ncol和nrow来制作2 x 2网格并将视觉效果放在相对的角落然后玩宽度但我无法在对角处获得视觉效果 .

require(ggplot2);require(gridExtra)
A <- ggplot(CO2, aes(x=Plant)) + geom_bar() +coord_flip() 
B <- ggplot(CO2, aes(x=Type)) + geom_bar() +coord_flip() 
grid.arrange(A, B, ncol=1)

enter image description here

8 回答

  • 0

    试试这个,

    gA <- ggplotGrob(A)
     gB <- ggplotGrob(B)
     maxWidth = grid::unit.pmax(gA$widths[2:5], gB$widths[2:5])
     gA$widths[2:5] <- as.list(maxWidth)
     gB$widths[2:5] <- as.list(maxWidth)
     grid.arrange(gA, gB, ncol=1)
    

    编辑

    这是一个更通用的解决方案(适用于任意数量的图),使用 gridExtra 中包含的 rbind.gtable 的修改版本

    gA <- ggplotGrob(A)
    gB <- ggplotGrob(B)
    grid::grid.newpage()
    grid::grid.draw(rbind(gA, gB))
    
  • 34

    我想对任意数量的情节进行概括 . 以下是使用Baptiste方法的逐步解决方案:

    plots <- list(A, B, C, D)
    grobs <- list()
    widths <- list()
    

    收集每个图的每个grob的宽度

    for (i in 1:length(plots)){
        grobs[[i]] <- ggplotGrob(plots[[i]])
        widths[[i]] <- grobs[[i]]$widths[2:5]
    }
    

    使用do.call获取最大宽度

    maxwidth <- do.call(grid::unit.pmax, widths)
    

    将最大宽度设置为每个grob

    for (i in 1:length(grobs)){
         grobs[[i]]$widths[2:5] <- as.list(maxwidth)
    }
    

    情节

    do.call("grid.arrange", c(grobs, ncol = 1))
    
  • 12

    使用cowplot包:

    A <- ggplot(CO2, aes(x=Plant)) + geom_bar() +coord_flip() 
    B <- ggplot(CO2, aes(x=Type)) + geom_bar() +coord_flip() 
    
    library(cowplot)
    plot_grid(A, B, ncol=1, align="v")
    

    enter image description here

  • 122

    http://rpubs.com/MarkusLoew/13295是一个非常简单的解决方案(最后一项)应用于此问题:

    require(ggplot2);require(gridExtra)
    A <- ggplot(CO2, aes(x=Plant)) + geom_bar() +coord_flip() 
    B <- ggplot(CO2, aes(x=Type)) + geom_bar() +coord_flip() 
    grid.draw(rbind(ggplotGrob(A), ggplotGrob(B), size="first"))
    

    您也可以将它用于宽度和高度:

    require(ggplot2);require(gridExtra)
    A <- ggplot(CO2, aes(x=Plant)) + geom_bar() +coord_flip() 
    B <- ggplot(CO2, aes(x=Type)) + geom_bar() +coord_flip() 
    C <- ggplot(CO2, aes(x=conc)) + geom_bar() +coord_flip()
    D <- ggplot(CO2, aes(x=uptake)) + geom_bar() +coord_flip() 
    grid.draw(cbind(
                rbind(ggplotGrob(A), ggplotGrob(B), size="first"),
                rbind(ggplotGrob(C), ggplotGrob(D), size="first"),
                size='first'))
    
  • 7

    这是使用reshape2包中的 meltfacet_wrap 的另一种可能的解决方案:

    library(ggplot2)
    library(reshape2)
    
    dat = CO2[, c(1, 2)]
    dat$id = seq(nrow(dat))
    mdat = melt(dat, id.vars="id")
    
    head(mdat)
    #   id variable value
    # 1  1    Plant   Qn1
    # 2  2    Plant   Qn1
    # 3  3    Plant   Qn1
    # 4  4    Plant   Qn1
    # 5  5    Plant   Qn1
    # 6  6    Plant   Qn1
    
    plot_1 = ggplot(mdat, aes(x=value)) + 
             geom_bar() + 
             coord_flip() +
             facet_wrap(~ variable, nrow=2, scales="free", drop=TRUE)
    
    ggsave(plot=plot_1, filename="plot_1.png", height=4, width=6)
    

    enter image description here

  • 0

    egg 包将ggplot对象包装到标准化的 3x3 gtable中,使得任意ggplots之间的绘图面板对齐,包括刻面的ggplots .

    library(egg) # devtools::install_github('baptiste/egg')
    library(ggplot2)
    
    p1 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) +
      geom_point() 
    
    p2 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) +
      geom_point() + facet_wrap( ~ cyl, ncol=2, scales = "free") +
      guides(colour="none") +
      theme()
    
    ggarrange(p1, p2)
    

    enter image description here

  • 8

    充其量这是一个黑客:

    library(wq)
    layOut(list(A, 1, 2:16),  list(B, 2:3, 1:16))
    

    但感觉真的很不对劲 .

  • 23

    我知道这是一篇很老的帖子,而且它已经得到了回答,但我可以建议将@ baptiste的方法与 purrr 结合起来,使它看起来更漂亮:

    library(purrr)
    list(A, B) %>% 
      map(ggplotGrob) %>% 
      do.call(gridExtra::gtable_rbind, .) %>% 
      grid::grid.draw()
    

相关问题