如何为SpatRast制作以1.3为分界的非线性发散色阶栅格图?
栅格发散色阶可视化解决方案(分段+连续映射)
需求回顾
- 处理
SpatRast栅格对象,变量下限为0,1.3为分界点:值<1.3代表空间离散,>1.3代表空间聚集 - 支持分段区间映射和连续变量映射两种可视化方式
- 两种方式的图例必须保持「0在下、最大值在上」的顺序
一、分段区间映射方案
基于terra的修正实现
针对你之前用terra绘图时图例顺序反转的问题,我们可以关闭默认图例,手动自定义绘制反转后的图例:
library(terra) library(RColorBrewer) # 替换为你的SpatRast对象 set.seed(123) x <- rast(nrow=100, ncol=100) values(x) <- runif(ncell(x), 0, 30) # 定义断点与配色 bks <- c(0,0.4,0.8,1.3,2,4,8,15,30) cold <- rev(brewer.pal(3, "Blues")) # 离散区冷色调 warm <- brewer.pal(length(bks)-1 - length(cold), "Reds") # 聚集区暖色调 colors <- c(cold, warm) # 绘制栅格,关闭默认图例 plot(x, breaks = bks, col = colors, box=F, axes=F, legend=FALSE) # 手动绘制反转图例:0在下,最大值在上 terra::legend( "right", legend = rev(bks), # 反转断点顺序 fill = rev(colors), # 对应反转配色 border = NA, bty = "n", y.intersp = 1.2, title = "变量值" )
基于ggplot2的分段实现
ggplot2对图例顺序的控制更直观,适合快速调整:
library(terra) library(ggplot2) library(RColorBrewer) # 替换为你的SpatRast对象 set.seed(123) x <- rast(nrow=100, ncol=100) values(x) <- runif(ncell(x), 0, 30) bks <- c(0,0.4,0.8,1.3,2,4,8,15,30) cold <- rev(brewer.pal(3, "Blues")) warm <- brewer.pal(length(bks)-1 - length(cold), "Reds") colors <- c(cold, warm) # 转换为数据框 x_df <- as.data.frame(x, xy=TRUE) colnames(x_df) <- c("x", "y", "value") # 绘图:一键反转图例 ggplot(x_df, aes(x=x, y=y, fill=value)) + geom_raster() + scale_fill_gradientn( colors = colors, breaks = bks, limits = range(bks), guide = guide_colorbar( direction = "vertical", reverse = TRUE, # 核心:反转图例顺序 title = "变量值", frame.colour = NA ) ) + coord_equal() + theme_void()
二、连续变量映射方案
基于ggplot2的非线性连续映射
支持自定义色阶分布和非线性变换,完美适配聚集区数值跨度大的场景:
library(terra) library(ggplot2) library(scales) # 替换为你的SpatRast对象 set.seed(123) x <- rast(nrow=100, ncol=100) values(x) <- runif(ncell(x), 0, 30) mid_point <- 1.3 # 分界点 # 自定义发散配色:从冷到暖过渡,突出分界点 colors_cont <- c("#08306b", "#4292c6", "#f7fbff", "#fee0d2", "#de2d26", "#a50f15") ggplot(as.data.frame(x, xy=TRUE), aes(x=x, y=y, fill=value)) + geom_raster() + scale_fill_gradientn( colors = colors_cont, # 手动控制配色在数值区间的分布,强化分界点视觉差异 values = rescale(c(0, mid_point-0.5, mid_point, mid_point+0.5, 10, 30)), limits = c(0, 30), guide = guide_colorbar( direction = "vertical", reverse = TRUE, # 反转图例顺序 title = "变量值", frame.colour = NA ), # 可选:自定义非线性变换,压缩聚集区大数值的显示尺度 trans = trans_new( name = "custom_log", transform = function(x) ifelse(x <= mid_point, x, mid_point + log(x - mid_point + 1)), inverse = function(x) ifelse(x <= mid_point, x, exp(x - mid_point) + mid_point - 1) ) ) + coord_equal() + theme_void()
基于terra的连续映射实现
如果偏好terra的底层控制,可结合colorRampPalette生成连续配色,再手动绘制反转图例:
library(terra) library(RColorBrewer) # 替换为你的SpatRast对象 set.seed(123) x <- rast(nrow=100, ncol=100) values(x) <- runif(ncell(x), 0, 30) mid_point <- 1.3 # 生成连续发散配色 cold_pal <- colorRampPalette(rev(brewer.pal(3, "Blues"))) warm_pal <- colorRampPalette(brewer.pal(5, "Reds")) n_cold <- 50 # 离散区分段数 n_warm <- 100 # 聚集区分段数 colors_cont <- c(cold_pal(n_cold), warm_pal(n_warm)) # 生成连续映射的伪断点 bks_cont <- seq(0, 30, length.out = length(colors_cont)+1) # 绘制栅格,关闭默认图例 plot(x, breaks = bks_cont, col = colors_cont, box=F, axes=F, legend=FALSE) # 手动绘制反转图例 terra::legend( "right", legend = rev(seq(0, 30, by=5)), # 自定义刻度标签 fill = rev(colors_cont[seq(1, length(colors_cont), length.out=7)]), # 对应配色采样 border = NA, bty = "n", title = "变量值" )
内容的提问来源于stack exchange,提问作者Laura Roich
相关产品推荐
相关产品推荐

