如何保存含自定义全局轴标题的grid.arrange组合图
如何保存含自定义全局轴标题的grid.arrange组合图
我完全懂你遇到的问题——用grid.arrange()组合两个图并手动加了全局的x、y轴标题,但想保存的时候却发现这些标题死活存不下来,对吧?这是因为grid.arrange()本身是直接在绘图设备上输出图形,返回的不是标准的ggplot对象,所以用ggsave()存它的返回值自然识别不了那些额外加的标题。
下面给你两个简单可行的解决办法,你可以根据自己的习惯选:
方案一:用arrangeGrob()替代grid.arrange()(最小改动)
arrangeGrob()是grid.arrange()的“孪生兄弟”,它不会直接绘图,而是返回一个gtable格式的对象,这个对象可以被ggsave()完美识别。只需要把你的代码稍微调整一下:
library(ggplot2) library(gridExtra) library(grid) # 用于创建可自定义的文本对象 # 你的原有绘图代码保持不变 p1 <- ggplot(SR_data, aes(x = max_temp, y = obs_bathe)) + ggtitle("Bathing")+ theme(text = element_text(size = 13), axis.title = element_blank()) p2 <- ggplot(SR_data, aes(x = max_temp, y = obs_drink)) + ggtitle("Drinking")+ theme(text = element_text(size = 13), axis.title = element_blank()) # 用arrangeGrob创建可保存的gtable对象,用textGrob更灵活控制标题样式 grid_temp <- arrangeGrob( p1, p2, bottom = textGrob("Daily maximum temperature (°C)", gp = gpar(fontsize = 13)), left = textGrob("Number of observations", gp = gpar(fontsize = 13), rot = 90) ) # 直接用ggsave保存这个gtable对象 ggsave("combined_temp_plot.png", grid_temp, width = 10, height = 6, dpi = 300)
这里用textGrob()代替直接传字符串,是为了让全局标题的字体大小和你子图里的文本保持一致,rot = 90是让左侧标题垂直显示,和默认轴标题的样式对齐。
方案二:用patchwork包(更现代的多图组合工具)
如果你愿意尝试更顺手的工具,patchwork是目前R里处理多图组合最友好的包,它返回的是标准ggplot对象,全局轴标题的添加和保存都非常丝滑:
library(ggplot2) library(patchwork) # 原有绘图代码不变 p1 <- ggplot(SR_data, aes(x = max_temp, y = obs_bathe)) + ggtitle("Bathing")+ theme(text = element_text(size = 13), axis.title = element_blank()) p2 <- ggplot(SR_data, aes(x = max_temp, y = obs_drink)) + ggtitle("Drinking")+ theme(text = element_text(size = 13), axis.title = element_blank()) # 组合图并添加全局轴标题 combined_plot <- p1 + p2 + plot_layout(ncol = 2) + # 设置两列布局 # 添加全局y轴标题 labs(y = "Number of observations") + # 添加全局x轴标题(用tag放在底部中心) labs(tag = "Daily maximum temperature (°C)") + theme( plot.tag = element_text(hjust = 0.5, size = 13, margin = margin(t = 10)), # 调整底部标题的边距 axis.title.y = element_text(size = 13), # 确保子图的轴标题被隐藏(你已经设置了,这里是双重保险) axis.title.x = element_blank() ) # 直接保存,和存单个ggplot完全一样 ggsave("combined_temp_plot_patchwork.png", combined_plot, width = 10, height = 6, dpi = 300)
这个方案的好处是,以后你要调整布局(比如加行、加注释、统一图例)都非常方便,完全不用纠结gtable的细节。
最后用你提供的示例数据测试一下,确保代码能跑通:
# 生成示例数据 vec1 <- c(1,8,2,8,2,8,3,5,9,7,3) vec2 <- c(5,14,26,16,12,18,6,13,32,20,4) vec3 <- c(24,25,26,32,30,32,29,28,27,31,32) SR_data <- data.frame( obs_bathe = vec1, obs_drink = vec2, max_temp = vec3 )
不管用哪个方案,最后保存的图片里都会完整保留你需要的全局轴标题~
备注:内容来源于stack exchange,提问作者Mag
相关产品推荐
相关产品推荐

