Построение растра с экспоненциальной или квантильной цветовой шкалой, расходящейся около нуля - PullRequest
1 голос
/ 15 марта 2019

Я использую функцию R levelplot() из пакета rasterVis для построения стека из трех растров с одной изменяющейся цветовой шкалой.Я хотел бы изменить масштаб растровой цветовой шкалы, чтобы карта подчеркивала различия в более низких значениях.Это может быть сделано с помощью нелинейного объединения цветовых разрывов.

Я использую код из a gist , написанный @ 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')

1 Ответ

1 голос
/ 20 марта 2019

Вы, вероятно, можете избежать 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]

Затем передайте перерывы на 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

...