使用cowplot的plot_grid消除ggplot分面条目留白问题
问题
使用cowplot包的plot_grid函数拼接两个带相同分面的ggplot对象,想要实现不同X轴的网格图,只让第一个图显示分面文本。虽然通过theme把第二个图的strip.background和strip.text设为空白隐藏了分面条目,但拼接后该区域仍有留白。单独显示第二个图时分面条目已消失,拼接后留白重现;如果移除两个图的分面条目,留白就会消失。相关代码如下:
dat <- tibble(x1=1:10, x2=20:11, y=rnorm(x2/2 - x1), lab=rep(c("A", "B"), 5)) p1 <- ggplot(dat, aes(x1, y)) + geom_point() + facet_wrap(~lab, nrow=1) + theme(plot.margin=unit(c(0, 0, 0, 0), "in")) p2 <- ggplot(dat, aes(x2, y)) + geom_point() + facet_wrap(~lab, nrow=1) + theme( plot.margin=unit(c(0, 0, 0, 0), "in"), strip.background=element_blank(), strip.text=element_blank() ) plot_grid(p1, p2, nrow=2, align="h")
原因
facet_wrap会为分面图预留固定的strip区域空间,即便通过theme隐藏了文本和背景,该区域的尺寸参数依然存在。当plot_grid使用align="h"对齐时,会以两个图中最大的strip区域尺寸为基准对齐,第一个图的strip有内容、尺寸不为零,因此第二个图的预留strip空间会被保留,呈现出留白。
解决办法
方法1:修改第二个图的gtable布局,移除strip区域
借助gtable包手动调整第二个图的布局,将strip对应行的高度设为0:
library(gtable) library(grid) # 提取p2的gtable对象 g2 <- ggplotGrob(p2) # 定位strip对应的行 strip_rows <- which(grepl("strip", g2$layout$name)) # 将strip行的高度设为0 g2$heights[strip_rows] <- unit(0, "in") # 拼接p1和修改后的g2 plot_grid(p1, g2, nrow=2, align="h")
方法2:使用patchwork包替代cowplot
patchwork在处理分面对齐时逻辑更简洁,直接隐藏第二个图的strip后不会出现留白:
library(patchwork) p1 / p2 + plot_layout(guides = "collect")
方法3:在theme中直接设置strip高度为0
从根源上消除第二个图的strip预留空间,在theme里添加strip.height = unit(0, "in"):
p2 <- ggplot(dat, aes(x2, y)) + geom_point() + facet_wrap(~lab, nrow=1) + theme( plot.margin=unit(c(0, 0, 0, 0), "in"), strip.background=element_blank(), strip.text=element_blank(), strip.height = unit(0, "in") # 关键:设置strip高度为0 ) plot_grid(p1, p2, nrow=2, align="h")
内容的提问来源于stack exchange,提问作者brendaisy
相关产品推荐
相关产品推荐

