绘制以指数或分位数为颜色梯度的栅格图,其围绕零发散。

3
我正在使用rasterVis软件包中的levelplot()函数来绘制三个栅格图层,并采用单一发散颜色条。我想要改变栅格颜色条的比例尺,使得地图突出显示较低值之间的差异。这可以通过非线性分组实现。
我正在使用由@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')

2
如果您提供一个简单的可重现示例,就更容易帮助您了,其中包括可以用于测试和验证可能解决方案的样本输入和所需输出。请提供一些实际调用此函数的示例代码,以展示预期输出。 - MrFlick
听起来你需要将连续的字段值切割成因子向量(区间)。我经常使用 raster 对象完成这个任务,然后将它们传递到 ggplot 中。例如:as.data.frame(my_raster, xy = TRUE) %>% ggplot(aes(x,y, fill = cut_bins)) + geom_raster() + scale_fill_manual() + theme_void()。然后在 scale_fill_manual 中,您可以为每个区间指定值、断点和标签。完全掌控! - Rich Pauloo
1个回答

3
您可以避免使用diverge0,而是定义中断点向量,让levelplot处理其余部分。
library(rasterVis)

你可以手动定义换行:
```html

你可以手动定义换行:

```
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]

然后将断点传递给at,将刻度位置/标签传递给colorkey $ labels:

p <- levelplot(s, par.settings=RdBuTheme(), at=b, 
               colorkey=list(height=0.8, labels=list(at=b, labels=round(b, 2))))
p

enter image description here


感谢@jbaums。这与我所做的类似...我意识到为了自动选择间隔,我需要回到栅格数据,因为rasterVis对象中仅存储最小/最大值。 - Cotton.Rockwood

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接