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

如何正确使用scale_fill_gradientn()与scale_color_gradientn()?

解决scale_fill_gradientn固定颜色映射且不截断极值的问题

你的核心需求是保留固定的颜色-数值对应关系(对称但间隔不均),同时不截断超出[-2,2]的极值,而是让这些极值使用颜色映射的两端颜色,保证中间颜色刻度以0为中心且对应准确。

方法一:使用oob = scales::squish参数

scale_fill_gradientn的oob参数可控制超出limits范围的数值处理方式,scales::squish会把超出范围的数值“压缩”到limits边界,极值将使用两端颜色而非被截断为NA,同时中间颜色映射完全符合设定的breaks和colorscale。

修改后的代码:

library(tidyverse)

# 固定的颜色和断点
colorscale <- c("#760005", "#ec0013", "#ffa938", "#fdd28a", "#fefe53", "#ffffff", "#a2fd6e", "#00b44a", "#008180", "#2a23eb", "#a21fec")
breaks <- c(-2.00, -1.50, -1.20, -0.70, -0.50, 0.00, 0.50, 0.70, 1.20, 1.50, 2.00)

df <- data.frame(
  year = seq(2000:2020),
  value = c(0.24, 1.74, -2.33, 1.48, 0.38, 0.64, 0.97, -1.83, -1.25, -0.49, 3.15, -0.16, -0.12, 0.09, -1.67, -0.64, 0.39, 0.52, -0.58, 0.74, -1.24)
)

ggplot(data = df, aes(x = year, y = value, fill = value)) +
  theme_minimal() +
  geom_bar(stat = "identity", color = "#c5c5c5c5", linewidth = 0.25) +
  scale_fill_gradientn(
    colors = colorscale,
    values = scales::rescale(breaks),
    limits = c(-2, 2),
    oob = scales::squish,  # 关键参数:挤压超出范围的数值到边界
    na.value = "#e5e5e5",
    breaks = breaks,  # 显示自定义断点
    labels = breaks   # 断点标签与数值一致
  )

方法二:手动分箱+scale_fill_manual

如果需要更精确控制每个区间的颜色(明确每个断点间数值对应的颜色),可先将value按自定义breaks分箱,再用scale_fill_manual指定每个区间的颜色。

代码示例:

library(tidyverse)

colorscale <- c("#760005", "#ec0013", "#ffa938", "#fdd28a", "#fefe53", "#ffffff", "#a2fd6e", "#00b44a", "#008180", "#2a23eb", "#a21fec")
breaks <- c(-Inf, -2.00, -1.50, -1.20, -0.70, -0.50, 0.00, 0.50, 0.70, 1.20, 1.50, 2.00, Inf)  # 增加-inf和inf覆盖极值

df <- df %>%
  mutate(value_bin = cut(value, breaks = breaks, labels = colorscale))  # 按断点分箱,标签对应颜色

ggplot(data = df, aes(x = year, y = value, fill = value_bin)) +
  theme_minimal() +
  geom_bar(stat = "identity", color = "#c5c5c5c5", linewidth = 0.25) +
  scale_fill_manual(
    values = setNames(colorscale, colorscale),  # 颜色与分箱标签对应
    breaks = colorscale,
    labels = c("< -2", "-2~-1.5", "-1.5~-1.2", "-1.2~-0.7", "-0.7~-0.5", "-0.5~0", "0~0.5", "0.5~0.7", "0.7~1.2", "1.2~1.5", "1.5~2", ">2"),  # 自定义刻度标签
    name = "Value"
  )

两种方法的说明

  • 方法一适合需要渐变过渡的场景,既保留固定颜色映射,又让极值显示两端颜色,不丢失数据可视化信息。
  • 方法二更适合需要明确区间划分的场景,完全手动控制每个区间颜色,适配非均匀间隔的断点需求。

内容的提问来源于stack exchange,提问作者Steffen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 21:05:32