最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

r - Non-linear diverging color scale for raster plot - Stack Overflow

programmeradmin5浏览0评论

I have a SpatRast object that contains a positive variable with a lower bound at 0. However, values below 1.3 indicate spatial dispersion, whereas values above 1.3 indicate spatial concentration. Therefore, I would like to map this raster using a color scale that diverges at 1.3. The values would need to be mapped in two distinct ways, that is continuously and in intervals; however, for both of these representations, the resulting legend would need to show 0 at the bottom and the maximum value at the top.

Despite my various attempts, I cannot manage to obtain what I want. Here I report a minimal example and the resulting figure using an interval representation, in which however I am unable to display the legend in reverse order. I would then also need to produce the corresponding representation treating the variable as continuous.

I am not bound to any specific library. With terra it seems impossible to reverse the legend order and it also seems impossible to obtain a non-linear customization of the color scale when the variable is to be plotted continuously. But I have tried also with rasterVis and ggplot2, and in each of these cases I have stumbled upon other obstacles. Also, in my example I obtain the color palette with RColorBrewer, but again I am not specifically bound to this library.

Can anybody help me? Thanks.

library(RColorBrewer)
bks <- c(0,0.4,0.8,1.3,2,4,8,15,30)
cold <- rev(RColorBrewer::brewer.pal(3, "Blues"))
warm <- RColorBrewer::brewer.pal(((length(bks)-1)-length(cold)), "Reds")
colors <- c(cold, warm)
terra::plot(x,
     breaks = bks, 
     col = colors,
     box=F,
     axes=F)

I have a SpatRast object that contains a positive variable with a lower bound at 0. However, values below 1.3 indicate spatial dispersion, whereas values above 1.3 indicate spatial concentration. Therefore, I would like to map this raster using a color scale that diverges at 1.3. The values would need to be mapped in two distinct ways, that is continuously and in intervals; however, for both of these representations, the resulting legend would need to show 0 at the bottom and the maximum value at the top.

Despite my various attempts, I cannot manage to obtain what I want. Here I report a minimal example and the resulting figure using an interval representation, in which however I am unable to display the legend in reverse order. I would then also need to produce the corresponding representation treating the variable as continuous.

I am not bound to any specific library. With terra it seems impossible to reverse the legend order and it also seems impossible to obtain a non-linear customization of the color scale when the variable is to be plotted continuously. But I have tried also with rasterVis and ggplot2, and in each of these cases I have stumbled upon other obstacles. Also, in my example I obtain the color palette with RColorBrewer, but again I am not specifically bound to this library.

Can anybody help me? Thanks.

library(RColorBrewer)
bks <- c(0,0.4,0.8,1.3,2,4,8,15,30)
cold <- rev(RColorBrewer::brewer.pal(3, "Blues"))
warm <- RColorBrewer::brewer.pal(((length(bks)-1)-length(cold)), "Reds")
colors <- c(cold, warm)
terra::plot(x,
     breaks = bks, 
     col = colors,
     box=F,
     axes=F)

Share Improve this question asked Mar 17 at 17:59 Laura RoichLaura Roich 876 bronze badges 1
  • 1 When asking a question, please include a minimal, reproducible, self-contained example. Yours is not self-contained. You show a map, but you do not include the data to make that map. – Robert Hijmans Commented Mar 17 at 20:37
Add a comment  | 

1 Answer 1

Reset to default 2

Example data:

library(terra)
r <- rast(system.file("ex/elev.tif", package="terra"))
x <- scale_linear(r, 0, 30)
bks <- c(0,0.4,0.8,1.3,2,4,8,15,30)
colors <- c('#3182BD', '#9ECAE1', '#DEEBF7', '#FEE5D9', '#FCAE91',
            '#FB6A4A', '#DE2D26', '#A50F15')

With terra > 1.8-36, you can reverse the interval legend like this:

plot(x, col=colors, box=F, axes=F, breaks=bks, reverse=TRUE)
# or 
plot(classify(x, bks), col=colors, box=F, axes=F, reverse=TRUE)

With prior versions, you can achieve this by creating a categorical raster and use argument "sort" like this:

b <- classify(x, bks)
ord <- rev(levels(b)[[1]][,2])
terra::plot(b, col = colors, box=F, axes=F, sort=ord)

For the continuous legend, you can make two color palettes, and then create colors with each, proportionally to the range of values before and after the break

crp1 <- colorRampPalette(colors[1:3])
crp2 <- colorRampPalette(colors[4:8])
cols <- c(crp1(10), crp2(10 * (30-1.3)/1.3))
plot(x, col=cols, plg=list(at=c(0,1.3, 5, 10, 20, 30), digits=1), 
         range=c(0,30), axes=FALSE)

发布评论

评论列表(0)

  1. 暂无评论