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

使用自由缩放与混合格式标签时Patchwork面板对齐问题

解决patchwork拼接带facet_wrap的ggplot图形对齐问题

当拼接带facet_wrap(scales='free_y')的两个ggplot图形时,因y轴标签格式(货币/普通数字)宽度差异导致面板错位、x轴及标题无法合并,可通过以下方法解决:

方法1:统一y轴标签宽度+patchwork水平对齐

核心思路:计算货币格式标签的最大宽度,给普通数字标签补前导空格匹配宽度,再用plot_layout(align='h')实现水平对齐,同时统一x轴标题。

library(ggplot2)
library(patchwork)
library(scales)
library(stringr)

# 构造示例数据
set.seed(123)
df1 <- data.frame(
  category = rep(c("A", "B", "C"), each = 10),
  value = runif(30, 100, 1000)
)

df2 <- data.frame(
  category = rep(c("A", "B", "C"), each = 10),
  value = runif(30, 10, 100)
)

# 生成原始图形(隐藏顶部图的x轴标题)
p1 <- ggplot(df1, aes(x = category, y = value)) +
  geom_boxplot() +
  facet_wrap(~category, scales = "free_y") +
  scale_y_continuous(labels = dollar_format()) +
  labs(y = "金额", x = NULL)

# 计算货币标签的最大宽度
max_label_width <- max(str_width(dollar_format()(range(df1$value))))

# 调整p2的y轴标签,补空格匹配宽度
p2 <- ggplot(df2, aes(x = category, y = value)) +
  geom_boxplot() +
  facet_wrap(~category, scales = "free_y") +
  scale_y_continuous(labels = function(x) {
    str_pad(number(x, accuracy = 1), width = max_label_width, side = "left")
  }) +
  labs(y = "数量", x = "类别")

# 拼接并对齐
p1 / p2 + plot_layout(align = "h")

方法2:通过grid包手动调整grob宽度

直接操作图形的底层grob对象,强制两个图的y轴宽度一致:

library(grid)

# 转换为grob对象
g1 <- ggplotGrob(p1)
g2 <- ggplotGrob(p2)

# 让p2的y轴宽度和p1一致
g2$widths[2] <- g1$widths[2]

# 拼接绘制
grid.draw(rbind(g1, g2, size = "first"))

方法3:使用egg包的ggarrange(备选方案)

egg::ggarrange对带facet的图形对齐支持更简便:

library(egg)

ggarrange(p1, p2, ncol = 1, align = "hv")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 07:50:21