如何绘制基于特定离散分类的geom_raster?代码调试求助
问题:geom_raster按指定分类上色失败的解决办法
需求说明
希望绘制geom_raster,让填充色基于SPI的特定分段分类,尝试使用scale_fill_gradient的代码未达到预期效果。
用户尝试的代码片段
scale_fill_gradient(colours = c( "brown","burlywood","bisque","aliceblue","cadetblue2","blue"), breaks=c(-2,-1.5,-1,1,1.5,2), labels = format(c("-2","-1.5","-1","1","1.5","2")))
完整示例代码
year <- seq(1977,2021,1) jan = runif(45, min=-4, max=4) feb = runif(45, min=-4, max=4) mar = runif(45, min=-4, max=4) apr = runif(45, min=-4, max=4) may = runif(45, min=-4, max=4) jun = runif(45, min=-4, max=4) jul = runif(45, min=-4, max=4) aug = runif(45, min=-4, max=4) sep = runif(45, min=-4, max=4) oct = runif(45, min=-4, max=4) nov = runif(45, min=-4, max=4) dec = runif(45, min=-4, max=4) df = data.frame(year,jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dec) df <- reshape2::melt(df, id.vars = "year") df$year <- factor(df$year, levels = (unique(df$year))) df$variable <- factor(df$variable, levels = (unique(df$variable))) library(ggplot2) e1 <- ggplot(df, aes(x = variable, y = year, fill = value)) + geom_raster()+ guides(fill=guide_legend(title="Bohicon"))+ scale_fill_gradient(colours = c( "brown","burlywood","bisque","aliceblue","cadetblue2","blue"), breaks=c(-2,-1.5,-1,1,1.5,2), labels = format(c("-2","-1.5","-1","1","1.5","2")))+ theme(legend.position="bottom") e1
问题原因与解决方案
核心问题
scale_fill_gradient是连续渐变比例尺,但需求是分段式的分类颜色映射,且原代码的断点设置跳过了-1到1的区间,导致连续渐变无法匹配离散的分类逻辑,最终色阶不符合预期。
修正方案
提供两种实现方式,分别对应渐变过渡的分段色阶和严格离散的分类色块:
方式1:分段渐变(贴合参考图效果)
使用scale_fill_stepsn实现带过渡的分段色阶,匹配你的断点和颜色需求:
library(ggplot2) library(reshape2) # 生成数据 year <- seq(1977,2021,1) months <- replicate(12, runif(45, min=-4, max=4)) df <- data.frame(year, months) colnames(df)[-1] <- month.abb df <- melt(df, id.vars = "year") df$year <- factor(df$year, levels = unique(df$year)) df$variable <- factor(df$variable, levels = month.abb) # 定义断点和对应颜色 breaks <- c(-Inf, -2, -1.5, -1, 1, 1.5, 2, Inf) colors <- c("brown", "burlywood", "bisque", "aliceblue", "cadetblue2", "blue", "darkblue") e1 <- ggplot(df, aes(x = variable, y = year, fill = value)) + geom_raster()+ guides(fill=guide_colorbar(title="Bohicon", barwidth = 15))+ scale_fill_stepsn( colors = colors, breaks = breaks, labels = c("≤-2", "-2~-1.5", "-1.5~-1", "-1~1", "1~1.5", "1.5~2", "≥2"), limits = c(-4, 4) )+ theme(legend.position="bottom") e1
方式2:离散分类色块
先将连续的value变量转成离散分类,再用scale_fill_manual指定颜色:
# 给value分箱生成分类变量 df$spi_cat <- cut( df$value, breaks = c(-Inf, -2, -1.5, -1, 1, 1.5, 2, Inf), labels = c("≤-2", "-2~-1.5", "-1.5~-1", "-1~1", "1~1.5", "1.5~2", "≥2") ) e2 <- ggplot(df, aes(x = variable, y = year, fill = spi_cat)) + geom_raster()+ guides(fill=guide_legend(title="Bohicon"))+ scale_fill_manual( values = c("brown", "burlywood", "bisque", "aliceblue", "cadetblue2", "blue", "darkblue") )+ theme(legend.position="bottom") e2
关键说明
scale_fill_stepsn适合需要渐变过渡的分段色阶,和参考图效果更匹配;- 若需要无过渡的离散色块,优先选择先分箱再用
scale_fill_manual的方式; - 原代码中
guide_legend搭配连续比例尺会冲突,渐变类图例应使用guide_colorbar。
内容的提问来源于stack exchange,提问作者Marcel
相关产品推荐
相关产品推荐

