【问题标题】:ggplot2 and gridExtra: completely remove strip in facet_grid - not just invisibleggplot2 和 gridExtra:完全删除 facet_grid 中的条带 - 不仅仅是不可见
【发布时间】:2013-06-17 09:20:43
【问题描述】:

我有两个图表,我按以下方式将一个放在另一个之上:

library(ggplot2)
library(gridExtra)
p1 <- ggplot(mtcars, aes(mpg, wt)) + geom_point()
p2 <- ggplot(mtcars, aes(mpg, wt)) + geom_point()
p2 <- p2 + facet_grid(cyl ~ .)
grid.arrange(p1, p2, ncol=1)

为此,我需要将顶部和底部图的 x 轴对齐,但是由于左侧的条带,多面图比顶部图窄。我可以使用以下方法使条带不可见:

theme(strip.text.y = element_blank())
theme(strip.background = element_blank())

但是,这并不能消除条带占用的空间。所以我要么需要一种完全摆脱条带的方法,要么有一种方法将我的多面图拆分为单独的图,但以某种方式在它们之间共享相同的 y 轴标签。在我的图表中,我有两个不是很高的多面面板,并且没有足够的空间让它们每个都有一个合适大小的 y 轴。

有什么建议吗?

【问题讨论】:

  • 我的解决方法(在格子中,我更流利)是将条带添加到“简单”图中。

标签: r ggplot2 gridextra


【解决方案1】:

我的解决方案是找到条带的宽度,然后将两个图的边距设置为零,但将没有条带的那个缩小到略小(条带的宽度),以便它们出现 大小相同。通过反复试验,条带似乎大约有 0.5 行宽(但我想你可以通过编程方式解决这个问题)。因此,只需确保 没有 带状文本的绘图中的正确绘图边距比带有不可见带的那个大 0.5 行:

#  Add a line of width 0.5 on the left but set all other margins to zero
p1 <- p1 + theme( plot.margin = unit( c(0,0.5,0,0) , units = "lines" ) )
#  Set all margins to zero, the strip will take up a phantom amount of invisible space
p2 <- p2 + theme(strip.text.y = element_blank() , 
  strip.background = element_blank(),
  plot.margin = unit( c(0,0,0,0) , units = "lines" ) )

grid.arrange(p1, p2, ncol=1)

显然,您可以根据需要调整边距(例如,将 1 添加到 plot.margin 中每个数字向量的第一个位置,以获得沿每个图顶部的一条线的边框),只要您保留 0.5 行第二个图的右边框有更多边距,它们看起来是一样的。

【讨论】:

    【解决方案2】:

    使用gtable 包中的函数的另一种解决方案。它对齐图,但保留带状文本。它使用gtable 函数在p1 的右侧插入一列,该列等于p2 的条形文本的宽度。

    library(ggplot2)
    library(gridExtra)
    library(gtable)
    
    p1 <- ggplot(mtcars, aes(mpg, wt)) + geom_point()
    p2 <- ggplot(mtcars, aes(mpg, wt)) + geom_point()
    p2 <- p2 + facet_grid(cyl ~ .)
    
    g1 = ggplotGrob(p1)
    # gtable_show_layout(g1)  # View the layout
    # g1$widths               # Get the widths of g1
    
    g2 = ggplotGrob(p2)
    # gtable_show_layout(g2)  # View the layout
    # g2$widths               # Check the widths of g2
    
    #  Add new column to the right of g1 equal in width the strip width of g2.
    #  In g2, strip width is the 6th element the vector g2$widths
    g1 <- gtable_add_cols(g1, g2$widths[6])  
    grid.arrange(g1, g2, ncol=1)
    

    ## But note that if the y-axis titles and/or labels take up different widths, 
    #  the two plots are not aligned
    p1 <- ggplot(mtcars, aes(mpg, wt)) + geom_point() +
       theme(axis.title.y = element_text(vjust = .5, angle = 0, size = 30))
    p2 <- ggplot(mtcars, aes(mpg, wt)) + geom_point()
    p2 <- p2 + facet_grid(cyl ~ .)
    
    g1 = ggplotGrob(p1)
    g2 = ggplotGrob(p2)
    
    g1 <- gtable_add_cols(g1, g2$widths[6])  # New column added to the right
    grid.arrange(g1, g2, ncol=1)             # Plots are not aligned
    

    # Need to set widths to the maximums in the two plots, 
    # i.e., set g2 widths to be the same as g1 widths
    g2$widths <- g1$widths
    grid.arrange(g1, g2, ncol=1)            # Plots are aligned
    

    编辑: 或者按照 baptiste 的建议,使用 gtablerbind() 函数:

    g1 = ggplotGrob(p1)
    g2 = ggplotGrob(p2)
    
    g1 <- gtable_add_cols(g1, g2$widths[6], 5)  # New column added to the right 
    
    library(grid)
    grid.draw(rbind(g1, g2, size = "first"))
    

    【讨论】:

      【解决方案3】:

      这里使用viewportgrid.layout 的另一个解决方案。我创建了 2 个具有 2 个不同布局的视口。然后我使用参数 vp 放置 ggplot2 图。

      library(grid)
      pushViewport(plotViewport(c(1,1,1,1),layout = grid.layout(2, 1)))
      print(p2, vp = viewport(layout.pos.row = 2, layout.pos.col = 1))
      pushViewport(viewport(layout.pos.row=1,
        layout = grid.layout(1, 2,widths = unit(c(1,1),c("null",'lines')))))
      print(p1, vp = viewport(layout.pos.row = 1, layout.pos.col = 1))
      upViewport(2)             
      

      【讨论】:

        【解决方案4】:

        您也可以这样做并保留带标题,这将是相关信息:

        library(ggplot2)
        library(gridExtra)
        p1 <- ggplot(mtcars, aes(mpg, wt)) + geom_point() +
                 xlab(NULL)
        p2 <- ggplot(mtcars, aes(mpg, wt)) + geom_point() +
                 facet_wrap( ~ cyl, ncol = 1)
        grid.arrange(p1, p2, ncol=1)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-01-23
          • 2016-03-06
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多