【问题标题】:Preserve proportion of graphs using grid.arrange使用 grid.arrange 保留图形的比例
【发布时间】:2013-05-03 21:32:02
【问题描述】:

我正在尝试使用grid.arrange 安排多个绘图。 它按规定完成工作,并且在调用时:

p1 <- ggplot(subset(mtcars, cyl = 4), aes(wt, mpg, colour = cyl)) + geom_point() 
p2 <- ggplot(subset(mtcars, cyl = 8), aes(wt, mpg, colour = cyl)) + geom_point()

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

我得到了两个漂亮的地块,大小对称:

我的图表引用了不同的参数,但它们确实共享相同的组颜色编码。所以我想把这个图例从除一个之外的所有图例中删除,并为它找到一个好地方。

但是当我尝试时:

p3 <- ggplot(subset(mtcars, cyl = 8), aes(wt, mpg, colour = cyl)) + geom_point() + guides(colour=FALSE)

grid.arrange(p3, p2, ncol = 2)

没有图例的情节(正确地)变大了:

我想保持大小(作为 x 轴的长度)在图表中保持不变。

我知道我可以在这里使用分面,但我还需要组合各种(我认为)很难使用分面实现的图表。

grid.arrange 可以做到吗?任何其他解决方案可以在这里提供帮助?

【问题讨论】:

  • 您可以在没有grid.arrange 的情况下通过分面来完成此操作。但是mtcars 中没有class 列供我展示。
  • @Arun 对不起-我的错误。将示例切换到气缸。正如我所提到的,我知道刻面的魔力,但我想不使用它就离开。

标签: r ggplot2


【解决方案1】:

试试这个,它使用cbind.gtable

grid.draw(cbind(ggplotGrob(p3), ggplotGrob(p2), size="last"))

【讨论】:

  • +1 我有大约 20 行代码,我正要粘贴以通过一些手动操作来完成同样的事情。我希望我之前就知道cbind.gtable。谢谢。
  • @Josh 谢谢。确实很棒的解决方案。但是(和西蒙一样,我需要询问纵横比 - 是否可以保留?
  • @SimonO101 -- 好问题。看起来它没有提供这一点。如果你们中的任何一个想要追求这个,我可能会建议查看getAnywhere("cbind_gtable"),这是设置单位的地方,您可能想要修改代码。
  • @JoshO'Brien 在这种情况下,我可能只是粘贴允许控制纵横比的答案,但这比这更麻烦!
  • @SimonO101 -- 酷。我想请你这样做,很高兴你会这样做。
【解决方案2】:

不像@Josh 的解决方案那样优雅简单,但您可以使用 grid.arrange 来做到这一点,它允许您保留或指定绘图的纵横比,但您需要为您的图例创建一个tableGrob .我回答了一个类似的问题here,这是我从 ggplot2 图例中获得用于制作 tableGrob 的便捷代码的地方:

## Make a tableGrob of your legend
tmp <- ggplot_gtable(ggplot_build(p2))
leg <- which(sapply(tmp$grobs, function(x) x$name) == "guide-box")
legend <- tmp$grobs[[leg]]

# Plot objects using widths and height and respect to fix aspect ratios
# We make a grid layout with 3 columns, one each for the plots and one for the legend
grid.newpage()
pushViewport( viewport( layout = grid.layout( 1 , 3 , widths = unit( c( 0.4 , 0.4 , 0.2 ) , "npc" ) ,heights = unit( c( 0.45 , 0.45 , 0.45 ) , "npc" ) , respect = matrix(rep(1,3),1) ) ) ) 
print( p1 + theme(legend.position="none") , vp = viewport( layout.pos.row = 1 , layout.pos.col = 1 ) )
print( p2 + theme(legend.position="none") , vp = viewport( layout.pos.row = 1, layout.pos.col = 2 ) )
upViewport(0)
vp3 <- viewport( width = unit(0.2,"npc") , x = 0.9 , y = 0.5)
pushViewport(vp3)
grid.draw( legend )
popViewport()

【讨论】:

  • 非常感谢。尽管解决方案更长,但它可以完成工作。两个(新手)问题:1)宽度的单位总和为1吗? respect 参数指定了什么?
  • 我发现 respsect 参数有点混乱,但本质上我认为它是每个视口的纵横比矩阵,所以我们有1,1,1,因为我们有 1 行和 3 列,我们想要一个每个中的纵横比为 1:1。这可能不是完全它是如何工作的,但它对我有帮助!!!宽度单位必须总和为 1。您可以将它们挤入小于绘图区域的宽度。 “npc”是从 0 到 1,0 为绘图区域的左边缘或底部,1 为右边缘或顶部,0.5 为中心。相应地缩放。]
【解决方案3】:

我想我会更新这个帖子,因为grid.arrange 现在有这个功能:

grid.arrange(p3, p2, ncol = 2, widths = c(1,1.2))

【讨论】:

  • 谢谢!您是如何得出width 值的?这是近似值吗?
  • 我估计了相对比例,直到看起来正确为止。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-02
  • 1970-01-01
  • 1970-01-01
  • 2014-06-17
  • 1970-01-01
  • 2013-06-10
相关资源
最近更新 更多