ggsave保存ggpairs图时缺失对角直方图的问题求助
R 4.4.0升级后ggsave保存ggpairs图缺失对角直方图的排查建议
问题概述
几年前实现的ggpairs配对图对角直方图着色代码,在R版本升级至4.4.0后出现异常:RStudio的Plots窗口能正常显示完整图像(包含对角直方图),但用ggsave保存为JPEG格式时,生成的文件中缺失对角直方图。此前代码可正常运行。
代码重现
绘图代码
require(GGally) # 散点图+平滑趋势线函数 lower_plots <- function(data, mapping, ...) { ggplot(data = data, mapping = mapping) + geom_point(color = "black", shape = 1, size = 1, alpha = 1) + geom_smooth(method = "gam",...) } # 对角直方图函数(原全局变量实现) diag_plots <- function(data, mapping, ...) { # 全局计数器递增 x <<- x + 1 ggplot(data = data, mapping = mapping) + geom_histogram(fill = clrs[x], ...) } # 设置颜色与初始计数器 clrs <- c("red","green","blue","orange") x <- 0 # 生成配对图 ggpairs(iris,1:4, diag = list(continuous = wrap(diag_plots, bins = 15)), lower = list(continuous = wrap(lower_plots, color="red", se=FALSE))) + theme_light(base_size = 12) + theme(panel.grid.minor = element_blank(), panel.grid.major = element_blank()) + theme(plot.margin = unit(c(2.5,2.5,2.5,3.5), "lines"))
保存代码
ggsave(filename = "iris.JPG", device = "jpeg", width = 22, height = 18, units = "cm", dpi = 300)
排查思路与解决方案
核心原因:全局变量的副作用
原代码依赖全局变量x作为计数器分配颜色,但R 4.4.0(或配套的ggplot2/GGally版本更新)改变了绘图对象的渲染机制:
- 在RStudio窗口显示时,绘图对象仅渲染一次,全局变量
x从0递增到4,刚好匹配clrs的4个颜色。 - 调用
ggsave时,绘图对象会被重新渲染一次,此时全局变量x的初始值已经是4,再次递增后变成5,超出clrs的长度(clrs[5]为NA),导致直方图无法正常渲染。
修复方案:移除全局变量依赖
改用当前绘图变量的名称匹配颜色,避免全局状态干扰:
require(GGally) require(rlang) lower_plots <- function(data, mapping, ...) { ggplot(data = data, mapping = mapping) + geom_point(color = "black", shape = 1, size = 1, alpha = 1) + geom_smooth(method = "gam",...) } # 修改后的对角直方图函数 diag_plots <- function(data, mapping, ...) { # 获取当前x轴变量的名称 var_name <- get_expr(mapping$x) %>% as.character() # 匹配iris前4个变量的顺序,获取对应颜色索引 var_idx <- match(var_name, names(iris)[1:4]) ggplot(data = data, mapping = mapping) + geom_histogram(fill = clrs[var_idx], ...) } clrs <- c("red","green","blue","orange") # 生成配对图并赋值给变量 p <- ggpairs(iris,1:4, diag = list(continuous = wrap(diag_plots, bins = 15)), lower = list(continuous = wrap(lower_plots, color="red", se=FALSE))) + theme_light(base_size = 12) + theme(panel.grid.minor = element_blank(), panel.grid.major = element_blank()) + theme(plot.margin = unit(c(2.5,2.5,2.5,3.5), "lines")) # 保存图像 ggsave(filename = "iris.JPG", plot = p, device = "jpeg", width = 22, height = 18, units = "cm", dpi = 300)
额外排查建议
- 升级GGally到最新版本:运行
install.packages("GGally"),确保包版本与R 4.4.0兼容。 - 显式传递绘图对象:将生成的图赋值给变量后传入
ggsave,避免隐式重新渲染的不确定性。
内容的提问来源于stack exchange,提问作者Markm0705
相关产品推荐
相关产品推荐

