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

如何保存含自定义全局轴标题的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 18:30:29