使用自由缩放与混合格式标签时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
相关产品推荐
相关产品推荐

