如何在R中保存坐标轴长度一致的两个ggplot图(不受轴文本位数影响)
解决独立保存ggplot图时坐标轴长度不一致的问题
问题核心是ggplot会根据元素(如y轴文本)自动调整布局,导致相同尺寸设置下,实际绘图面板大小不同。以下是几种独立保存时保证坐标轴长度一致的方法:
方法1:使用gtable固定面板宽度
通过gtable包手动调整绘图对象的面板宽度,确保两张图的绘图区域完全一致:
library(ggplot2) library(gtable) set.seed(123) # 生成数据 x <- seq(0, 100, by = 1) y1 <- x + rnorm(length(x), mean = 0, sd = 10) y2 <- 200000 - x * 1000 + rnorm(length(x), mean = 0, sd = 10000) data1 <- data.frame(x = x, y1 = y1) data2 <- data.frame(x = x, y2 = y2) # 创建绘图对象 plot1 <- ggplot(data1, aes(x = x, y = y1)) + geom_point() + geom_smooth(method = "lm", col = "blue") + theme_bw() + theme(aspect.ratio = 0.75) plot2 <- ggplot(data2, aes(x = x, y = y2)) + geom_point() + geom_smooth(method = "lm", col = "red") + theme_bw() + theme(aspect.ratio = 0.75) # 转换为gtable对象 gt1 <- ggplotGrob(plot1) gt2 <- ggplotGrob(plot2) # 获取两张图的面板宽度,取较大值作为统一宽度 panel_width <- max(gt1$widths[gt1$layout$name == "panel"], gt2$widths[gt2$layout$name == "panel"]) # 设置两张图的面板宽度为统一值 gt1$widths[gt1$layout$name == "panel"] <- panel_width gt2$widths[gt2$layout$name == "panel"] <- panel_width # 保存调整后的图 setwd("C:/[your path]") tiff("plot1_fixed.tiff", units="in", height=3, width=4, res=200) grid::grid.draw(gt1) dev.off() tiff("plot2_fixed.tiff", units="in", height=3, width=4, res=200) grid::grid.draw(gt2) dev.off()
方法2:用cowplot对齐后独立保存
cowplot的align_plots函数可以对齐多张图的面板,之后分别导出:
library(ggplot2) library(cowplot) set.seed(123) # 生成数据和创建绘图对象 x <- seq(0, 100, by = 1) y1 <- x + rnorm(length(x), mean = 0, sd = 10) y2 <- 200000 - x * 1000 + rnorm(length(x), mean = 0, sd = 10000) data1 <- data.frame(x = x, y1 = y1) data2 <- data.frame(x = x, y2 = y2) plot1 <- ggplot(data1, aes(x = x, y = y1)) + geom_point() + geom_smooth(method = "lm", col = "blue") + theme_bw() + theme(aspect.ratio = 0.75) plot2 <- ggplot(data2, aes(x = x, y = y2)) + geom_point() + geom_smooth(method = "lm", col = "red") + theme_bw() + theme(aspect.ratio = 0.75) # 对齐两张图(垂直方向对齐,保证x轴长度一致) aligned_plots <- align_plots(plot1, plot2, align = "v", axis = "l") # 分别保存对齐后的图 setwd("C:/[your path]") tiff("plot1_aligned.tiff", units="in", height=3, width=4, res=200) grid::grid.draw(aligned_plots[[1]]) dev.off() tiff("plot2_aligned.tiff", units="in", height=3, width=4, res=200) grid::grid.draw(aligned_plots[[2]]) dev.off()
方法3:手动设置左侧边距
通过theme()的plot.margin手动调整左边距,给较长的y轴文本预留足够空间,同时让两张图的绘图区域一致:
library(ggplot2) set.seed(123) # 生成数据和创建绘图对象 x <- seq(0, 100, by = 1) y1 <- x + rnorm(length(x), mean = 0, sd = 10) y2 <- 200000 - x * 1000 + rnorm(length(x), mean = 0, sd = 10000) data1 <- data.frame(x = x, y1 = y1) data2 <- data.frame(x = x, y2 = y2) # 给两张图设置相同的左侧边距(根据较长y轴需求调整) common_margin <- margin(5.5, 5.5, 5.5, 20, unit = "pt") plot1 <- ggplot(data1, aes(x = x, y = y1)) + geom_point() + geom_smooth(method = "lm", col = "blue") + theme_bw() + theme(aspect.ratio = 0.75, plot.margin = common_margin) plot2 <- ggplot(data2, aes(x = x, y = y2)) + geom_point() + geom_smooth(method = "lm", col = "red") + theme_bw() + theme(aspect.ratio = 0.75, plot.margin = common_margin) # 保存图片 setwd("C:/[your path]") tiff("plot1_margin.tiff", units="in", height=3, width=4, res=200) grid::grid.draw(plot1) dev.off() tiff("plot2_margin.tiff", units="in", height=3, width=4, res=200) grid::grid.draw(plot2) dev.off()
方法1和方法2为自动对齐,准确性更高;方法3适合快速测试,需手动调整边距参数。
内容的提问来源于stack exchange,提问作者Giuseppe Petri
相关产品推荐
相关产品推荐

