如何为Gratia绘制的多幅GAM图设置自定义红-绿色阶
解决gratia绘制GAM张量平滑项偏效应图的色阶统一问题
问题场景
用mgcv拟合包含两个张量平滑项的GAM模型,代码如下:
library(mgcv) # 拟合GAM模型 gam_model <- gam( score ~ te(duration, difference) + te(duration, temperature) + season, data = my_data )
使用gratia::draw()绘制偏效应图时,希望将色阶改为低值红色、高值绿色,但尝试直接添加scale_fill_gradient仅第二个张量图生效;拆分绘制时也只有一幅图色阶改变,且所有绘图均出现警告:
Scale for fill is already present. Adding another scale for fill, which will replace the existing scale.
解决方案
问题根源是gratia会为每个张量平滑项的子图单独设置fill的取值范围,导致自定义色阶仅覆盖最后一个子图的映射。以下是三种可行解决方法:
方法1:统一色阶取值范围(推荐)
先提取所有张量项的效应值全局范围,再以此为基准设置色阶的limits,让所有子图共用同一映射:
library(gratia) library(ggplot2) # 提取两个张量平滑项的效应值,计算全局取值范围 sm_estimates <- smooth_estimates(gam_model, terms = c("te(duration, difference)", "te(duration, temperature)")) global_val_range <- range(sm_estimates$estimate) # 绘制并应用统一红绿色阶 gam_plot <- draw(gam_model, contour = FALSE) + scale_fill_gradient(low = "red", high = "green", limits = global_val_range) print(gam_plot)
方法2:手动拼接单独绘制的子图
拆分绘制每个张量项时,明确指定统一的取值范围,再用cowplot拼接:
library(gratia) library(ggplot2) library(cowplot) # 复用方法1中计算的全局取值范围 # 绘制第一个张量项并替换色阶 plot1 <- draw(gam_model, terms = "te(duration, difference)", contour = FALSE) + scale_fill_gradient(low = "red", high = "green", limits = global_val_range) # 绘制第二个张量项并替换色阶 plot2 <- draw(gam_model, terms = "te(duration, temperature)", contour = FALSE) + scale_fill_gradient(low = "red", high = "green", limits = global_val_range) # 拼接两幅图 plot_grid(plot1, plot2, ncol = 2)
方法3:全局修改gratia默认色阶
如果希望所有gratia绘图都默认使用红绿色阶,可修改全局主题:
library(gratia) library(ggplot2) # 覆盖gratia的默认fill色阶 theme_set(theme_gam() + scale_fill_gradient(low = "red", high = "green")) # 直接绘图即可自动应用自定义色阶 draw(gam_model, contour = FALSE)
内容的提问来源于stack exchange,提问作者Math Lover
相关产品推荐
相关产品推荐

