How to assign a specific color to NA in an image plot

r

Solution

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(...)
}

Problem

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(...) } ```

Original source