How do we convert a single band categorial raster to a three-dimensional RGB array?
Lets say we want to define the color per value(category) and get an RGB array with corresponding decimal RGB values.
E.g. in the example below how would I get rgb_array given r and myCol?
library(raster)
# sample raster
r <- raster(ncol=4, nrow=4)
r[] <- c(rep(1, 8), rep(2, 8))
# plot 1=red, 2=blue
myCol = c("red", "blue")
plot(r, col=myCol)
# rgb_array is the desired output, but how to get it programatically from r?
red_band <- c(rep(255, 8), rep(0, 8))
green_band <- c(rep(0, 8), rep(0, 8))
blue_band <- c(rep(0, 8), rep(255, 8))
rgb_array <- array(c(red_band, green_band, blue_band), dim= c(4, 4, 3))
You can do this with terra::subst
.
Example data
library(terra)
#terra 1.6.21
x <- rast(ncol=4, nrow=4, vals=c(rep(1, 8), rep(2, 8)))
Solution
from <- 1:2
to <- t(col2rgb(c("red", "blue")))
r <- subst(x, from, to, names=c("red", "green", "blue"))
plotRGB(r)
And to a three-dimensional array from r
, you can do
ar <- as.array(r)
You can also use terra::colorize
for that. But thanks to your question I found a bug in that method so you need to use "terra" version 1.6-21 or higher. That is currently the development version that you can install like this: install.packages('terra', repos='https://rspatial.r-universe.dev')
Set the color table that matches the values with a color, and use colorize
.
coltab(x) <- data.frame(value=1:2, col=c("red", "blue"))
rgb <- colorize(x, "rgb")
rgb
#class : SpatRaster
#dimensions : 4, 4, 3 (nrow, ncol, nlyr)
#resolution : 90, 45 (x, y)
#extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
#coord. ref. : +proj=longlat +datum=WGS84 +no_defs
#source : memory
#colors RGB : 1, 2, 3
#names : red, green, blue
#min values : 0, 0, 0
#max values : 255, 0, 255
And now you can do
plot(rgb)
ar2 <- as.array(rgb)
To get the equivalent to plot(x)
(because x
has a color-table)