Search code examples
rplotcolorsraster

Plotting a raster layer by setting a specific color to a non-central value


I have been trying to plot a raster layer by setting the value 1 to the color white. I looked at many examples but still couldn't construct the colors as I wish. I want contrasting colors for the values below and above 1. I would like them start with a light tone and get darker as they go further from 1. I also posted the figure that I managed to create so far. It looks a bit weird since it is based on made up data. I can't share the real data unfortunately. The best would be to create this using viridis colors, but I don't know how doable it is.

I wonder if anyone has any suggestions?

I got the idea of breakpoints and colors from the following post :https://gis.stackexchange.com/questions/17339/raster-legend-in-r-how-to-colour-specific-values .

I got the shapefile from here : https://gadm.org/download_country.html .

Here is my example:

library(rgdal)
library(raster)
library(sp)
library(sf)

set.seed(123)

proj = "+units=km +proj=utm +zone=37 +ellps=clrk80 +towgs84=-160,-6,-302,0,0,0,0 +no_defs"

map0 = readOGR(dsn = "dataFiles/gadm40_NGA_shp",   #https://gadm.org/download_country.html (Nigeria/shapefile)
           layer = "gadm40_NGA_0")

map0_trnsfrmd = spTransform(map0,proj) 

predRaster <- raster(ncol=400, nrow=400, xmn=-3805.7869, xmx=-2222.120, ymn=562.5405, ymx=1828.165)

res(predRaster) = 5

projection(predRaster) = "+units=km +proj=utm +zone=37 +ellps=clrk80 +towgs84=-160,-6,-302,0,0,0,0 +no_defs"

idx = 1:80201 # index for the cell numbers

val = c(rnorm(50000), rep(1,10201),runif(20000,min=0, max=3))

r = setValues(predRaster, values = val, index=idx) # assign values to the cells

r = raster::mask(crop(r, extent(map0_trnsfrmd)), map0_trnsfrmd, snap = 'out')

below=val[val<1]
above=val[val>1]

min(below)
[1] -4.289319
max(above)
[1] 4.438207
max(below)
[1] 0.9998253
min(above)
[1] 1.000105

breakpoints = c(-4.289319, 0.9998253, 1.000105, 4.438207)

colors = c("red","white","blue")

par(mgp=c(4,1,0), mar=c(5,7,3,1)+0.1)

plot(r,las=1, asp = 1, xlab="Easting", ylab="Northing", axis.args = list(cex.axis=1),
 legend.shrink =1,legend.width=2, cex.lab=2, cex.axis=1.5, legend.args = list("title", cex =1),breaks=breakpoints,col=colors)

exampleplot


Solution

  • Please look below on the colors definition. I have removed the shape for clarity.

    library(rgdal)
    library(raster)
    library(sp)
    library(sf)
    
    set.seed(123)
    
    predRaster <- raster(ncol=400, nrow=400, xmn=-3805.7869, xmx=-2222.120, ymn=562.5405, ymx=1828.165)
    res(predRaster) = 5
    projection(predRaster) = "+units=km +proj=utm +zone=37 +ellps=clrk80 +towgs84=-160,-6,-302,0,0,0,0 +no_defs"
    idx = 1:80201 # index for the cell numbers
    val = c(rnorm(50000), rep(1,10201),runif(20000,min=0, max=3))
    r = setValues(predRaster, values = val, index=idx) # assign values to the cells
    
    below=val[val<1]
    above=val[val>1]
    
    colors = c(colorRampPalette(c(rgb(1,0,0,1), rgb(1,0,0,0.1)), alpha = TRUE)(19),"white", colorRampPalette(c(rgb(0,0,1,0.1), rgb(0,0,1,1)), alpha = TRUE)(19))
    
    plot(r, col=colors, xlab="Easting", ylab="Northing", axis.args = list(cex.axis=1),
        legend.shrink =1,legend.width=2, cex.axis=1.5, legend.args = list("title", cex =1))
    

    You can increase the number of colors on both sides. Please check the help for colorRampPalette() function.

    Created on 2022-08-31 by the reprex package (v2.0.1)