How to assign a specific NA color to an image graph

I use the image command to build the matrix, the matrix contains some NA values. I use image as

 image(figData, zlim = zRange, col = colors, useRaster=TRUE) 

zRange less than the actual range of figData . I use the top color palette in the following group, which is compatible with red-green color perception imperfections:

http://www.mathworks.com/matlabcentral/fx_files/31761/6/thumbnail_184481.jpg

I want to select a specific color for the NA values ​​in figData that is outside of the colors (e.g. gray ). NA values ​​are now displayed by the last colors ( white ) element, so I cannot distinguish them from values ​​outside the range.

Ideally, I would like the solution to work no matter what color palette I use.

I want something similar to the na.color parameter in heatmap.2 , how can I do this? I want to change the source code of image to do this, but image seems to call the rasterImage function, the source code of which I cannot find.


After accepting Jealie's answer, I include the code here in my account differently for values ​​below and above the range:

 image.nan <- function(z, zlim, col, na.color='gray', outside.below.color='black', outside.above.color='white',...) { zstep <- (zlim[2] - zlim[1]) / length(col); # step in the color palette newz.below.outside <- zlim[1] - zstep # new z for values below zlim newz.above.outside <- zlim[2] + zstep # new z for values above zlim newz.na <- zlim[2] + 2 * zstep # new z for NA z[which(z<zlim[1])] <- newz.below.outside # we affect newz.below.outside z[which(z>zlim[2])] <- newz.above.outside # we affect newz.above.outside z[which(is.na(z>zlim[2]))] <- newz.na # same for newz.na zlim[1] <- zlim[1] - zstep # extend lower limit to include below value zlim[2] <- zlim[2] + 2 * zstep # extend top limit to include the two new values above and na col <- c(outside.below.color, col, outside.above.color, na.color) # we construct the new color range by including: na.color and na.outside image(z=z, zlim=zlim, col=col, ...) # we finally call image(...) } 
+6
source share
2 answers

Small correction: values ​​on the outside are not matched with the last col element, but they are not displayed instead (and the color does not look white ..).

Otherwise, to answer your question, the easiest way is to write a wrapper around image with two new arguments: na.color and outside.color . Here is my suggestion, which defaults to gray for NA and white for values ​​outside zlim :

 my.image <- function(figData, zlim, col, na.color='gray', outside.color='white', ...) { newz.na <- zlim[2]+(zlim[2]-zlim[1])/length(col) # new z for NA newz.outside <- zlim[2]+2*(zlim[2]-zlim[1])/length(col) # new z for values outside zlim figData$z[which(is.na(figData$z>zlim[2]))] <- newz.na # we affect newz.outside figData$z[which(figData$z<zlim[1] | figData$z>zlim[2])] <- newz.outside # same for newz.na zlim[2] <- zlim[2]+2*(zlim[2]-zlim[1])/length(col) # we finally extend the z limits to include the two new values col <- c(col, na.color, outside.color) # we construct the new color range by including: na.color and outside.color image(figData, zlim=zlim, col=col, ...) # we finally call image(...) } 
+2
source

Since color intervals are defined as (*bottom*, *top*] , values ​​in z equal to zlim [1] will be colored with the outer .below.color (because the range of the outer .below.color is ( *zlim[1] - zstep* , *zlim[1]* ] ).

The next version fixes this error:

 image.nan.better <- function(z, zlim, col, na.color='gray', outside.below.color='black', outside.above.color='white',...) { zstep <- (zlim[2] - zlim[1]) / length(col); # step in the color palette newz.below.outside <- zlim[1] - 2 * zstep # new z for values below zlim newz.above.outside <- zlim[2] + zstep # new z for values above zlim newz.na <- zlim[2] + 2 * zstep # new z for NA z[which(z<zlim[1])] <- newz.below.outside # we affect newz.below.outside z[which(z>zlim[2])] <- newz.above.outside # we affect newz.above.outside z[which(is.na(z>zlim[2]))] <- newz.na # same for newz.na zlim[1] <- zlim[1] - 2 * zstep # extend lower limit to include below value zlim[2] <- zlim[2] + 2 * zstep # extend top limit to include the two new values above and na col <- c(outside.below.color, col[1], col, outside.above.color, na.color) #correct by including col[1] at bottom of range image(z=z, zlim=zlim, col=col, ...) # we finally call image(...) } 

compare:

 f = matrix(abs(rnorm(300)),nrow=50) f[which(f>1)]=1 f[44,4] = 0 f[41,4] = NA f[42,4] = NA f[43,4] = NA f[44,3] = -1 f[44,5] = 2 image(as.matrix(f),col=c('green3','green2','blue1','blue3'),zlim=c(0,1)) image.nan(as.matrix(f),col=c('green3','green2','blue1','blue3'),zlim=c(0,1),outside.below.color='red',outside.above.color='brown',na.color='yellow') image.nan.better(as.matrix(f),col=c('green3','green2','blue1','blue3'),zlim=c(0,1),outside.below.color='red',outside.above.color='brown',na.color='yellow') 
+2
source

All Articles