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

使用egg::ggarrange实现组合图共享坐标轴标签的问题求助

解决egg::ggarrange共享轴标签位置问题

我想用egg::ggarrange把多张图组合成共享X、Y轴标签的图,尝试了以下代码,但遇到问题:X轴和Y轴标签出现在图注(子图标题)之后,且距离过远。

原尝试代码:

library(ggplot2)
df <- data.frame(
  x = 1:10, y1 = 1:10, y2 = (1:10)^2, y3 = (1:10)^3, y4 = (1:10)^4
)

p1 <- ggplot(df, aes(x, y1)) + geom_point() + theme(axis.title.x = element_blank(),
                                                    axis.title.y = element_blank())
p2 <- ggplot(df, aes(x, y2)) + geom_point() + theme(axis.title.x = element_blank(),
                                                    axis.title.y = element_blank())
p3 <- ggplot(df, aes(x, y3)) + geom_point() + theme(axis.title.x = element_blank(),
                                                    axis.title.y = element_blank())
p4 <- ggplot(df, aes(x, y4)) + geom_point() + theme(axis.title.x = element_blank(),
                                                    axis.title.y = element_blank())

# Create a simple grid
p <- plot_grid(p1, p2, p3, p4, align = 'hv')

p + draw_figure_label(label = "Figure 1")

p <- Map(function(a, b) {
  a + 
    labs(caption = b) + 
    theme(plot.caption.position = 'panel',
          plot.caption = element_text(hjust = 0.5, size = 12, face = 2,
                                      margin = margin(10, 0, 30, 0)))
}, 
a = list(p1, p2, p3, p4),
b = list('(a) Figure 1', '(b) Figure 2', '(c) Figure 3', '(d) Figure 4'))

graph <- egg::ggarrange(p[[1]], p[[2]], p[[3]], p[[4]])

annotate_figure(graph, left = textGrob("axis-y", rot = 90, vjust = 1, gp = gpar(cex = 0.8)),
                bottom = textGrob("axis-x", gp = gpar(cex = 0.8)))

修正方案

问题根源是子图的plot.caption设置了底部30单位的margin,导致子图下方多出大量空白,同时annotate_figure的标签位置未对齐。以下是两种可行的修正方法:

方法一:直接用ggarrange参数添加轴标签

library(ggplot2)
library(egg)
library(grid)

df <- data.frame(
  x = 1:10, y1 = 1:10, y2 = (1:10)^2, y3 = (1:10)^3, y4 = (1:10)^4
)

p1 <- ggplot(df, aes(x, y1)) + geom_point() + theme(axis.title.x = element_blank(),
                                                    axis.title.y = element_blank())
p2 <- ggplot(df, aes(x, y2)) + geom_point() + theme(axis.title.x = element_blank(),
                                                    axis.title.y = element_blank())
p3 <- ggplot(df, aes(x, y3)) + geom_point() + theme(axis.title.x = element_blank(),
                                                    axis.title.y = element_blank())
p4 <- ggplot(df, aes(x, y4)) + geom_point() + theme(axis.title.x = element_blank(),
                                                    axis.title.y = element_blank())

# 移除子图caption底部的多余margin
p <- Map(function(a, b) {
  a + 
    labs(caption = b) + 
    theme(plot.caption.position = 'panel',
          plot.caption = element_text(hjust = 0.5, size = 12, face = 2,
                                      margin = margin(10, 0, 0, 0)))
}, 
a = list(p1, p2, p3, p4),
b = list('(a) Figure 1', '(b) Figure 2', '(c) Figure 3', '(d) Figure 4'))

# 直接在ggarrange中指定轴标签,自动对齐到组合图边缘
graph <- egg::ggarrange(p[[1]], p[[2]], p[[3]], p[[4]],
                        bottom = textGrob("axis-x", gp = gpar(cex = 0.8)),
                        left = textGrob("axis-y", rot = 90, vjust = 0.5, gp = gpar(cex = 0.8)))
graph

方法二:修正annotate_figure的标签位置

library(ggplot2)
library(egg)
library(grid)

df <- data.frame(
  x = 1:10, y1 = 1:10, y2 = (1:10)^2, y3 = (1:10)^3, y4 = (1:10)^4
)

p1 <- ggplot(df, aes(x, y1)) + geom_point() + theme(axis.title.x = element_blank(),
                                                    axis.title.y = element_blank())
p2 <- ggplot(df, aes(x, y2)) + geom_point() + theme(axis.title.x = element_blank(),
                                                    axis.title.y = element_blank())
p3 <- ggplot(df, aes(x, y3)) + geom_point() + theme(axis.title.x = element_blank(),
                                                    axis.title.y = element_blank())
p4 <- ggplot(df, aes(x, y4)) + geom_point() + theme(axis.title.x = element_blank(),
                                                    axis.title.y = element_blank())

# 移除子图caption底部的多余margin
p <- Map(function(a, b) {
  a + 
    labs(caption = b) + 
    theme(plot.caption.position = 'panel',
          plot.caption = element_text(hjust = 0.5, size = 12, face = 2,
                                      margin = margin(10, 0, 0, 0)))
}, 
a = list(p1, p2, p3, p4),
b = list('(a) Figure 1', '(b) Figure 2', '(c) Figure 3', '(d) Figure 4'))

graph <- egg::ggarrange(p[[1]], p[[2]], p[[3]], p[[4]])

# 调整标签对齐方式,通过margin控制与图的距离
annotate_figure(graph, 
                left = textGrob("axis-y", rot = 90, vjust = 0.5, gp = gpar(cex = 0.8)),
                bottom = textGrob("axis-x", gp = gpar(cex = 0.8)),
                bottom_margin = unit(0.5, "lines"),
                left_margin = unit(0.5, "lines"))

内容的提问来源于stack exchange,提问作者Velton Sousa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 08:01:32