You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 07:25:21