Home > OS >  Plotting terra raster with white color set for 0 values
Plotting terra raster with white color set for 0 values

Time:09-07

I have a raster in terra that has values that ranges around 0. I want my negative values to be blue and positive values to be red. This question has already been ask enter image description here

You can see that the white color was not fixed to the zero value. Thats is probably because terra::plot calculate it's own range which is different from mine.

Reading around enter image description here

and:

coltab(rr) <- data.frame(
  val=values(rr),
  col=the_palette_fc(values(rr)))

plot(rr)

enter image description here

But the result do not seem to give the wanted results. Also, there is no legend automatically added which is also necessary. Maybe the coltab argument should be only used for categorical values?

So is there a way in terra to fined tune the colors palette so white is fix for 0 values?

CodePudding user response:

To set 0 as the midpoint, you can set the domain of your palette to c(-max(rr[]), max(rr[])):

the_palette_fc <- leaflet::colorNumeric(palette = "RdBu", 
                                        domain = c(-max(rr[]), max(rr[])),
                                        reverse = TRUE)

the_colors <- the_palette_fc(seq(min(rr[]), max(rr[]), length.out = 50))

plot(rr, col = the_colors)

enter image description here

If you want the scale to go from darkest blue to darkest red with a transition of white at 0, it is a bit more involved, but you could do:

the_palette_fc <- leaflet::colorNumeric(palette = "RdBu", 
                                        domain = c(-max(rr[]), max(rr[])),
                                        reverse = TRUE)

breakpoints <- seq(min(rr[]), max(rr[]), length.out = 50)

the_colors <- the_palette_fc(c(seq(-max(rr[]), 0, length = sum(breakpoints < 0)),
                              seq(0, max(rr[]), length = sum(breakpoints > 0))))

plot(rr, col = the_colors)

enter image description here

CodePudding user response:

terra::plot actually does have a "breaks" argument; but it is only documented in the examples so it was easy to overlook. You can do

library(terra)
set.seed(1234)
rr <- rast(matrix(rnorm(400, 1.5, 1), nrow=20, ncol=20))
ceil <- values(rr) |> abs() |> max() |> ceiling() 
pal <- leaflet::colorNumeric(palette = "RdBu", domain=c(-ceil, ceil), reverse = T)

b <- seq(-ceil, ceil, 1)
plot(rr, type="interval", breaks=b, col=pal(b))

enter image description here

In response to your comment:

For your purposes, you can also use the range argument, I think.

plot(rr, range=c(-ceil, ceil), col=pal(seq(-ceil,ceil,.1)))

enter image description here

And if you use "breaks", with terra 1.6-14 (currently the development version) you can now overwrite the default legend type.

plot(rr, type="cont", breaks=b, col=pal(b))

enter image description here

  • Related