使用arrangeGrob在叠加图中均衡ggplot2面板高度

Met*_*hic 2 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")

# 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);
Run Code Online (Sandbox Code Playgroud)

合并的图如下所示.我特别宽和短,以便您可以看到问题:arrangeGrob均衡绘图高度,但这样做会使绘图面板具有不同的高度.底部面板被底部图上的x轴标签和刻度标签压扁,顶部图缺少.

http://ofb.net/~frederik/stack1/out.svg

现在,我可以回收用来均衡宽度的技巧.取消注释该行

g1g$heights=g2g$heights
Run Code Online (Sandbox Code Playgroud)

得到以下结果:

http://ofb.net/~frederik/stack1/height-attempt.svg

这不是我想要的,因为现在出现在地块之间的过多的垂直空间 - 我希望它们能够触摸.

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

g=arrangeGrob(g1g,g2g,heights=c(1,2))
Run Code Online (Sandbox Code Playgroud)

但是,我必须弄清楚这些数字,直到它看起来正确.

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

bap*_*ste 6

改用rbind,

grid.draw(rbind(ggplotGrob(g1), ggplotGrob(g2)))
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

如果你想摆脱介于两者之间的空间,那么从gtable中删除这些行比删除绘图边距更容易(你手动更改主题设置会产生错误,所以我忽略了这些行).

grid.newpage()
grid.draw(rbind(ggplotGrob(g1)[-(4:6),], ggplotGrob(g2)[-(1:2),]))
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

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

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)))
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述