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

如何固定ggplot2图例各数值区间颜色?实现多数据集图例一致性

问题:固定产量分布图的颜色区间与图例一致性

我需要用Data1和Data2两组数据集,在同一区域绘制median_mafruit的产量分布图,要求固定图例中不同数值区间的对应颜色,但当前代码生成的结果不符合预期:即使数据未达到3.5,图例中仍出现蓝色,且颜色与区间的对应关系和设定不符。

现有代码

library(ggplot2)
library(dplyr)
library(readr)

color_breaks <- c(0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0)
colors <- c("#E31A1C", "#FF7F00","#FDBF6F","#E9E4A6", "#A4D4A9", "#B2DF8A", "#33A02C", "#1F78B4")

p1<-ggplot(merged_data, aes(x = longitude, y = latitude, z = median_mafruit)) +
  stat_summary_2d(bins = 30) + 
  scale_fill_gradientn(
    colors = colors,
    values = scales::rescale(color_breaks),
    breaks = color_breaks,
    labels = scales::number_format(accuracy = 0.1)
  ) +
  labs(
    title = "Data2",
    x = "Longitude",
    y = "Latitude",
    fill = expression("Amount")
  ) +
  theme_minimal() +
  theme(
    plot.title = element_text(size = 16, face = "bold"),
    plot.subtitle = element_text(size = 14, face = "italic"),
    legend.title = element_text(size = 12),
    legend.text = element_text(size = 10)
  )
p1

数据示例(Data2部分数据)

merged_data <- structure(list(Order = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 
13, 14, 15, 16, 17, 18, 19, 20), latitude = c(43.2143, 43.3697, 
43.3909, 43.3926, 43.3961, 43.3978, 43.066, 43.2215, 43.368, 
43.435, 43.4434, 43.4623, 43.4895, 43.4856, 43.3738, 43.4761, 
43.5102, 43.5118, 43.5062, 43.4933), longitude = c(-4.479, -4.4804, 
-4.4606, -4.4484, -4.4241, -4.412, -4.1046, -4.1049, -4.1031, 
-4.0818, -4.021, -3.9502, -3.8184, -3.7798, -3.7279, -3.7147, 
-3.5971, -3.5849, -3.5585, -3.5177), median_mafruit = c(2.73, 
1.095, 1.115, 2.73, 0.527, 0.527, 0.962, 1.039, 1.039, 2.73, 
2.73, 2.73, 2.73, 2.73, 0.544, 2.73, 2.73, 2.73, 0.478, 2.73)), row.names = c(NA, 
-20L), spec = structure(list(cols = list(Order = structure(list(), class = c("collector_double", 
"collector")), latitude = structure(list(), class = c("collector_double", 
"collector")), longitude = structure(list(), class = c("collector_double", 
"collector")), median_mafruit = structure(list(), class = c("collector_double", 
"collector"))), default = structure(list(), class = c("collector_guess", 
"collector")), delim = ","), class = "col_spec"), problems = <pointer: 0x0000024c6289c0f0>, class = c("spec_tbl_df", 
"tbl_df", "tbl", "data.frame"))

核心需求

无论使用哪组数据集,颜色必须严格遵循以下区间映射:

  • [0, 0.5) → #E31A1C
  • [0.5, 1) → #FF7F00
  • [1, 1.5) → #FDBF6F
  • [1.5, 2) → #E9E4A6
  • [2, 2.5) → #A4D4A9
  • [2.5, 3) → #B2DF8A
  • [3, 3.5) → #33A02C
  • [3.5, 4) → #1F78B4

即使数据未覆盖高区间(比如最大值不到3),也要保留对应区间的图例项,且Data1与Data2的图例完全一致。


解决方案

问题出在scale_fill_gradientn是基于连续渐变的颜色映射,会自动适配当前数据集的数值范围,导致区间和颜色对应混乱。改用scale_fill_stepsn可以实现固定区间的离散颜色映射,同时通过设置limits强制所有图使用同一数值标尺。

修改后的代码:

library(ggplot2)
library(dplyr)
library(readr)

color_breaks <- c(0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0)
colors <- c("#E31A1C", "#FF7F00","#FDBF6F","#E9E4A6", "#A4D4A9", "#B2DF8A", "#33A02C", "#1F78B4")
# 自定义区间标签
interval_labels <- c(
  "0-0.5", "0.5-1", "1-1.5", "1.5-2",
  "2-2.5", "2.5-3", "3-3.5", "3.5-4"
)

p1<-ggplot(merged_data, aes(x = longitude, y = latitude, z = median_mafruit)) +
  stat_summary_2d(bins = 30) + 
  scale_fill_stepsn(
    colors = colors,
    breaks = color_breaks,
    limits = range(color_breaks), # 固定数值范围,确保所有图用同一标尺
    labels = interval_labels,
    show.limits = TRUE, # 显示完整的区间范围
    oob = scales::squish, # 超出范围的数据压缩到最近区间
    name = "Amount" # 图例标题
  ) +
  labs(
    title = "Data2",
    x = "Longitude",
    y = "Latitude"
  ) +
  theme_minimal() +
  theme(
    plot.title = element_text(size = 16, face = "bold"),
    plot.subtitle = element_text(size = 14, face = "italic"),
    legend.title = element_text(size = 12),
    legend.text = element_text(size = 10)
  )
p1

关键修改说明

  1. scale_fill_stepsn替代scale_fill_gradientn:专门用于分段式的颜色映射,严格对应你定义的区间和颜色。
  2. limits = range(color_breaks):强制颜色映射的数值范围为0到4,不管当前数据集的最大值是多少,保证不同数据集的图例完全一致。
  3. 自定义labels:直接显示区间范围,更清晰直观。
  4. oob = scales::squish:如果数据中有超出0-4范围的值,会自动压缩到0或4对应的区间,避免报错或异常颜色。

这样修改后,无论Data1还是Data2,都会使用完全一致的图例和颜色区间,即使数据未覆盖高区间,图例也会保留所有8个区间的项和对应颜色。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 01:02:05