Reputation: 10117
I have an array with dimension (28,28,3) height, width, depth. Each depth is one of the RGB channels. The values are between 0 and 1.
I want to use the image() function to plot the image. The z argument is a matrix. How can I convert the array into a matrix in order to be able to plot?
My final goal is to have something like this but with color images.
Upvotes: 1
Views: 2555
Reputation: 47051
With the raster package you can do
R <- matrix(rep(sin(seq(0, 2*pi, length.out = 31))^2, length.out = 900), nrow = 30)
G <- matrix(rep(cos(seq(0, 2*pi, length.out = 15))^2, length.out = 900), nrow = 30)
B <- matrix(rep(sin(seq(pi, 2*pi, length.out = 30))^2, length.out = 900), nrow = 30)
my_img <- c(R, G, B)
dim(my_img) <- c(30, 30, 3)
library(raster)
b <- brick(my_img)
crs(b) <- "+proj=tmerc"
plotRGB(b, scale=1)
# or
plotRGB(b, scale=1, interpolate=TRUE)
Upvotes: 0
Reputation: 173793
The problem with graphics::image
is that it will not plot your 3D array as a colour image. It plots a matrix as a heatmap.
Let's take a colorful patterned image:
R <- matrix(rep(sin(seq(0, 2*pi, length.out = 31))^2, length.out = 900), nrow = 30)
G <- matrix(rep(cos(seq(0, 2*pi, length.out = 15))^2, length.out = 900), nrow = 30)
B <- matrix(rep(sin(seq(pi, 2*pi, length.out = 30))^2, length.out = 900), nrow = 30)
my_img <- c(R, G, B)
dim(my_img) <- c(30, 30, 3)
Now if I plot this with raster
as @IanCampbell suggests, I get my desired image:
plot(raster::as.raster(my_img))
whereas if I plot one layer (here the red channel) using image
, I get a heatmap:
image(R)
If you really want to use image
, then you would have to average all your layers, but then you lose colour information, and still get a heat map:
image((R + B + G)/3)
So the bottom line is that if you want to plot a colour image, then image is not the function you are looking for. There are lots of ways to plot multiple colour images in a single R window, so saying that you have to use image
because you need to plot a grid of images just isn't true.
For example:
grid.arrange(rasterGrob(my_img), rasterGrob(1-my_img),
rasterGrob(1-my_img), rasterGrob(my_img), ncol = 2)
Upvotes: 3
Reputation: 24770
One approach is with rasterImage
set.seed(3)
data <- replicate(4,array(data = runif(28*28*3,0,1),
dim = c(28,28,3)), simplify = FALSE)
par(mfrow=c(2, 2), mar=c(0, 0, 3, 0))
sapply(seq_along(data), function(x){
plot.new()
rasterImage(data[[x]], xleft = 0, xright = 1,
ytop = 0, ybottom = 1, interpolate = FALSE)
title(paste0("Plot ",x))
})
Upvotes: 4