R语言诊断图中平方根标准化残差轴font.lab=2不生效问题
模型诊断图轴标签粗体问题分析与解决
复现代码
df <- structure(list(sales1 = c(11.3208, 12.9151, 18.8947, 14.6739, 8.6493, 9.5238, 7.6923, 0.0017, 8.0477, 6.7358, 6.1441, 21.7939, 4.2553, 0.0017, 11.0196, 6.2762, 13.2316, 5.0676, 5.6235, 14.9893 ), store = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L), levels = c("1", "2", "3", "4", "5", "6"), class = "factor"), day = structure(c(1L, 2L, 3L, 4L, 5L, 6L, 1L, 2L, 3L, 4L, 5L, 6L, 1L, 2L, 3L, 4L, 5L, 6L, 1L, 2L), levels = c("1", "2", "3", "4", "5", "6"), class = "factor")), row.names = c(NA, 20L), class = "data.frame") par(mfrow= c(2,2), mgp=c(2, .7, 0), mai=c(0.7, 0.7, 0.7, 0.1), font.lab = 2) a1 <- aov(sales1 ~ store + day, df) plot(a1)

问题现象
设置font.lab = 2后,模型诊断图的多数轴标签变为粗体,但左下角子图的y轴标签(平方根标准化残差)未生效。
问题原因
这是因为plot.aov()绘制左下角的Scale-Location图时,其y轴标签是通过mtext()手动添加的,没有继承全局par(font.lab)参数。R基础绘图中,部分特殊子图的元素会绕过全局参数,直接使用默认样式渲染。
简便替代方案
方案1:修改基础绘图函数的标签逻辑
直接重写plot.aov的部分行为,让所有标签都应用粗体设置:
# 重写plot.aov函数,补全Scale-Location图的粗体标签 plot.aov <- function(x, ...) { # 调用原生plot.aov绘图 graphics:::plot.aov(x, ...) # 定位到左下角子图区域 par(fig = c(0, 0.5, 0, 0.5), new = TRUE) # 重新绘制粗体y轴标签 mtext("Square Root of Standardized Residuals", side = 2, line = 2, font = 2, cex = par("cex.lab")) # 恢复全局绘图区域设置 par(fig = c(0,1,0,1), new = FALSE) } # 重新运行绘图代码 par(mfrow= c(2,2), mgp=c(2, .7, 0), mai=c(0.7, 0.7, 0.7, 0.1), font.lab = 2) plot(a1)
方案2:用ggplot2重构诊断图(更灵活可控)
如果不想修改基础函数,使用ggplot2结合broom包生成诊断图,可完全自定义样式:
library(ggplot2) library(broom) # 提取模型诊断数据 diagnostic_data <- augment(a1) %>% mutate( std_resid = rstandard(a1), sqrt_abs_std_resid = sqrt(abs(std_resid)), leverage = hatvalues(a1) ) # 绘制四个诊断图 ggplot() + # 残差-拟合值图 geom_point(data = diagnostic_data, aes(.fitted, .resid)) + geom_hline(yintercept = 0, linetype = 2) + labs(x = "Fitted Values", y = "Residuals") + # QQ图 geom_qq(data = diagnostic_data, aes(sample = std_resid)) + geom_qq_line(data = diagnostic_data, aes(sample = std_resid)) + labs(x = "Theoretical Quantiles", y = "Standardized Residuals") + # Scale-Location图 geom_point(data = diagnostic_data, aes(.fitted, sqrt_abs_std_resid)) + geom_smooth(data = diagnostic_data, aes(.fitted, sqrt_abs_std_resid), se = FALSE) + labs(x = "Fitted Values", y = "Square Root of Standardized Residuals") + # 残差-杠杆图 geom_point(data = diagnostic_data, aes(leverage, std_resid)) + geom_smooth(data = diagnostic_data, aes(leverage, std_resid), se = FALSE) + labs(x = "Leverage", y = "Standardized Residuals") + # 全局设置:所有轴标签粗体 theme(axis.title = element_text(face = "bold")) + # 分面布局 facet_wrap(~.panel, ncol = 2, scales = "free")
内容的提问来源于stack exchange,提问作者Ann
相关产品推荐
相关产品推荐

