使用arrangeGrob均衡堆叠地块中的ggplot2面板高度

使用arrangeGrob均衡堆叠地块中的ggplot2面板高度,r,ggplot2,gridextra,R,Ggplot2,Gridextra,我有两组时间序列数据,我想以叠加的方式绘制。到目前为止,我已经能够想出这样的办法: library(ggplot2); library(gridExtra); t=1:100; s=sin(t/10); c=cos(t/10); g1=ggplot()+theme_bw()+geom_line(aes(x=t,y=s))+ylab(NULL) g2=ggplot()+theme_bw()+geom_line(aes(x=t,y=c))+ylab("Cosine")+xlab("Time")

我有两组时间序列数据,我想以叠加的方式绘制。到目前为止,我已经能够想出这样的办法:

library(ggplot2);
library(gridExtra);

t=1:100; s=sin(t/10); c=cos(t/10);
g1=ggplot()+theme_bw()+geom_line(aes(x=t,y=s))+ylab(NULL)
g2=ggplot()+theme_bw()+geom_line(aes(x=t,y=c))+ylab("Cosine")+xlab("Time")

# get rid of the top plot's axis labels
g1=g1+theme(
  axis.text.x=element_blank(),
  panel.margin = unit(0,"null")
  );
g1=g1+labs(x=NULL);

# zero bottom margin of top plot
g1$theme$plot.margin[3]=unit(0,"null");

# zero top margin of bottom plot
g2$theme$plot.margin[1]=unit(0,"null");

# this trick equalizes the width of the two plot panels
g1g=ggplotGrob(g1);
g2g=ggplotGrob(g2);
g1g$widths=g2g$widths

# however, equalizing the heights of the panels is not so simple as
# the following:
# g1g$heights=g2g$heights

g=arrangeGrob(g1g,g2g)

plot(g)   #ggsave("out.svg",g,width=5,height=1.5);
组合图如下所示。我把它弄得特别宽而且 缩短,以便您可以看到问题:
arrangeGrob
使 打印高度,但这样做会使打印面板具有不同的 高度。底部面板被x轴标签压扁并打勾 底部打印上的标签,而顶部打印缺少标签

现在,我可以重复我用来平衡宽度的技巧。取消行的注释

g1g$heights=g2g$heights
产生以下结果:

这不是我想要的,因为现在在两个图之间出现了过多的垂直空间——我希望它们是触动的

我知道我可以将
heights
参数传递给arrangeGrob,以指定绘图的相对高度:

g=arrangeGrob(g1g,g2g,heights=c(1,2))
但是,我必须摆弄这些数字,直到它看起来正确为止

我想知道是否有一种简单的方法,可以在渲染最终grob时自动强制两个面板具有相同的高度。

使用rbind

grid.draw(rbind(ggplotGrob(g1), ggplotGrob(g2)))

如果你想去掉中间的空间,从GTTable中删除这些行要比弄乱绘图页边距容易得多(你对主题设置的手动更改产生了一个错误,所以我忽略了这些行)

必须在单独的步骤中更改面板高度,例如使用此小辅助功能

g12 <- rbind(ggplotGrob(g1)[-(4:6),], ggplotGrob(g2)[-(1:2),])

resize_heights <- function(g, heights = rep(1, length(idpanels))){
  idpanels <- unique(g$layout[grepl("panel",g$layout$name), "t"])
  g$heights <- grid:::unit.list(g$heights)
  g$heights[idpanels] <- unit.c(do.call(unit, list(heights, 'null')))
  g
}

grid.newpage()
grid.draw(resize_heights(g12, c(3,1)))

g12抱歉,我的问题中有内联图像,但我不得不将它们转换为链接,因为我的声誉太低了:/谢谢,这是一个很好的解决方案。我特别喜欢现在不必手动编辑主题。顺便说一句,我想一定是在过去五个月内添加了
rbind
?因为我必须升级gridExtra和ggplot2才能让它工作。。。我想我应该记得更频繁地升级。
rbind.gtable
实际上已经在gtable中使用了很多年,但是我最近在gridExtra中导出了一个稍微修改过的副本,因为原始版本无法处理这个非常常见的用例。我明白了。顺便问一下,如果我想让一个图(面板)的高度是另一个图(面板)的两倍,有没有办法使用rbind获得这种效果?谢谢!请举例说明如何手动编辑高度,好吗?我认为这可能对遇到我的问题的人有用,因为我最初使用的技术可以进行这样的调整。。。我不太熟悉“unit”数据类型,也不知道它有多强大。例如,我注意到有一个“grobheight”单位,这是否意味着我可以将同一表格中一个grob的高度(或宽度)设置为另一个grob高度的1.5倍?或者最简单的方法是什么?再次感谢!我刚看到你更新了答案。。。对不起,我忘了把它标为“已接受”。
g12 <- rbind(ggplotGrob(g1)[-(4:6),], ggplotGrob(g2)[-(1:2),])

resize_heights <- function(g, heights = rep(1, length(idpanels))){
  idpanels <- unique(g$layout[grepl("panel",g$layout$name), "t"])
  g$heights <- grid:::unit.list(g$heights)
  g$heights[idpanels] <- unit.c(do.call(unit, list(heights, 'null')))
  g
}

grid.newpage()
grid.draw(resize_heights(g12, c(3,1)))