绘制具有围绕零发散的指数或分位数色带的栅格
Plotting a raster with exponential or quantile color ramp diverging around zero
我正在使用 rasterVis
包中的 R 函数 levelplot()
来绘制具有单个发散色带的三个栅格堆栈。我想更改栅格色带的比例,以便地图突出较低值的差异。这可以通过颜色中断的非线性合并来完成。
我正在使用 a gist written by @jbaums 中的代码(下面包含代码)。关于如何调整此代码中的颜色渐变以使中断遵循 2^x 但保留最小值和最大值的任何建议?似乎改变 s
的顺序(如下)会产生预期的效果。
diverge0 <- function(p, ramp) {
# p: a trellis object resulting from rasterVis::levelplot
# ramp: the name of an RColorBrewer palette (as character), a character
# vector of colour names to interpolate, or a colorRampPalette.
require(RColorBrewer)
require(rasterVis)
if(length(ramp)==1 && is.character(ramp) && ramp %in%
row.names(brewer.pal.info)) {
ramp <- suppressWarnings(colorRampPalette(brewer.pal(11, ramp)))
} else if(length(ramp) > 1 && is.character(ramp) && all(ramp %in% colors())) {
ramp <- colorRampPalette(ramp)
} else if(!is.function(ramp))
stop('ramp should be either the name of a RColorBrewer palette, ',
'a vector of colours to be interpolated, or a colorRampPalette.')
rng <- range(p$legend[[1]]$args$key$at)
s <- seq(-max(abs(rng)), max(abs(rng)), len=1001)
i <- findInterval(rng[which.min(abs(rng))], s)
zlim <- switch(which.min(abs(rng)), `1`=i:(1000+1), `2`=1:(i+1))
p$legend[[1]]$args$key$at <- s[zlim]
p$par.settings$regions$col <- ramp(1000)[zlim[-length(zlim)]]
p
}
下面是一些应用此功能的代码:
library (rasterVis)
ras1 <- raster(nrow=10,ncol=10)
set.seed(1)
ras1[] <- rchisq(df=10,n=10*10)
ras2 <- ras1*(-1)/2
s <- stack(ras1,ras2)
p <- levelplot(s, par.settings=RdBuTheme())
diverge0(p, ramp='RdBu')
您可能可以避免 diverge0
这样做,而是定义中断向量并让 levelplot
处理其余部分。
library(rasterVis)
您可以手动定义中断:
b <- c(-10.289, -8, -4, -2, -1, 0, 1, 2, 4, 8, 16, 20.578)
或自动化:
rng <- range(cellStats(s, range))
lim <- ceiling(log(abs(rng), 2))
b <- sort(c(0, unique(unlist(mapply(function(x, y) y*2^(0:x), lim, sign(rng))))))
b[1] <- rng[1]
b[length(b)] <- rng[2]
然后将 breaks 传递给 at
,将 tick locations/labels 传递给 colorkey$labels
:
p <- levelplot(s, par.settings=RdBuTheme(), at=b,
colorkey=list(height=0.8, labels=list(at=b, labels=round(b, 2))))
p
我正在使用 rasterVis
包中的 R 函数 levelplot()
来绘制具有单个发散色带的三个栅格堆栈。我想更改栅格色带的比例,以便地图突出较低值的差异。这可以通过颜色中断的非线性合并来完成。
我正在使用 a gist written by @jbaums 中的代码(下面包含代码)。关于如何调整此代码中的颜色渐变以使中断遵循 2^x 但保留最小值和最大值的任何建议?似乎改变 s
的顺序(如下)会产生预期的效果。
diverge0 <- function(p, ramp) {
# p: a trellis object resulting from rasterVis::levelplot
# ramp: the name of an RColorBrewer palette (as character), a character
# vector of colour names to interpolate, or a colorRampPalette.
require(RColorBrewer)
require(rasterVis)
if(length(ramp)==1 && is.character(ramp) && ramp %in%
row.names(brewer.pal.info)) {
ramp <- suppressWarnings(colorRampPalette(brewer.pal(11, ramp)))
} else if(length(ramp) > 1 && is.character(ramp) && all(ramp %in% colors())) {
ramp <- colorRampPalette(ramp)
} else if(!is.function(ramp))
stop('ramp should be either the name of a RColorBrewer palette, ',
'a vector of colours to be interpolated, or a colorRampPalette.')
rng <- range(p$legend[[1]]$args$key$at)
s <- seq(-max(abs(rng)), max(abs(rng)), len=1001)
i <- findInterval(rng[which.min(abs(rng))], s)
zlim <- switch(which.min(abs(rng)), `1`=i:(1000+1), `2`=1:(i+1))
p$legend[[1]]$args$key$at <- s[zlim]
p$par.settings$regions$col <- ramp(1000)[zlim[-length(zlim)]]
p
}
下面是一些应用此功能的代码:
library (rasterVis)
ras1 <- raster(nrow=10,ncol=10)
set.seed(1)
ras1[] <- rchisq(df=10,n=10*10)
ras2 <- ras1*(-1)/2
s <- stack(ras1,ras2)
p <- levelplot(s, par.settings=RdBuTheme())
diverge0(p, ramp='RdBu')
您可能可以避免 diverge0
这样做,而是定义中断向量并让 levelplot
处理其余部分。
library(rasterVis)
您可以手动定义中断:
b <- c(-10.289, -8, -4, -2, -1, 0, 1, 2, 4, 8, 16, 20.578)
或自动化:
rng <- range(cellStats(s, range))
lim <- ceiling(log(abs(rng), 2))
b <- sort(c(0, unique(unlist(mapply(function(x, y) y*2^(0:x), lim, sign(rng))))))
b[1] <- rng[1]
b[length(b)] <- rng[2]
然后将 breaks 传递给 at
,将 tick locations/labels 传递给 colorkey$labels
:
p <- levelplot(s, par.settings=RdBuTheme(), at=b,
colorkey=list(height=0.8, labels=list(at=b, labels=round(b, 2))))
p