I am using the image command to plot a matrix, the matrix contains some NA values. I am using image like
image(figData, zlim = zRange, col = colors, useRaster=TRUE)
zRange is smaller than the actual range of the figData. I am using the top colormap in the following group, which is compatible with red-green color perception deficiencies:
http://www.mathworks.com/matlabcentral/fx_files/31761/6/thumbnail_184481.jpg
I want to select a specific color for NA values in figData that is outside colors (for example, gray). NA values are being mapped now to the last element of colors (white) and therefore I can't distinguish them from out of range values.
Ideally I would like a solution that works no matter which color palette I am using.
I want something similar to the na.color option in heatmap.2, how can I do it? I am willing to modify the image source code to accomplish this, but image seems to call the rasterImage function whose source code I can't find.
After accepting Jealie's answer I am including here the code to 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(...)
}
Small correction: values outside are not being mapped to the last element of col, but they are instead not being plotted at all (and no color looks white..).
Otherwise, to answer your question, the simplest 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 values 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(...)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With