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

如何为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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 03:32:36