flamearchon
flamearchon

Reputation: 375

Contrasting color for NaNs in imagesc

I fill unused elements in a matrix with NaNs, and I would like to assign a contrasting color to those elements with the NaN value when displaying the data using imagesc.

Below is a link to a possible solution, but I don't quite understand it.

http://www.mathworks.com/matlabcentral/newsreader/view_thread/19985

Upvotes: 7

Views: 8252

Answers (3)

dkv
dkv

Reputation: 7292

This question shows up first in my search engine, but I found a much more preferable answer in this post so I thought I would include it here.

In summary, use the following:

imagesc(Z,'AlphaData',~isnan(Z))

Alternatively, note that pcolor ignores nans by default.

Upvotes: 1

yuk
yuk

Reputation: 19870

NaN values get the first color from the axes colormap, which by default corresponds to the minimum value (other than NaN). You can change the color for minimum value setting axes color limits with CAXIS function. To assign a contrast color to NaN values you can add a special color for NaN values as a first color (1x3 vector).

I take your example and made a function (with some comments):

function [h hcb] = imagescwithnan(a,cm,nanclr)
% IMAGESC with NaNs assigning a specific color to NaNs

%# find minimum and maximum
amin=min(a(:));
amax=max(a(:));
%# size of colormap
n = size(cm,1);
%# color step
dmap=(amax-amin)/n;

%# standard imagesc
him = imagesc(a);
%# add nan color to colormap
colormap([nanclr; cm]);
%# changing color limits
caxis([amin-dmap amax]);
%# place a colorbar
hcb = colorbar;
%# change Y limit for colorbar to avoid showing NaN color
ylim(hcb,[amin amax])

if nargout > 0
    h = him;
end

Here caxis statement assigns the first color of the color map not to the minimum value amin, but to the amin-dmap. So the first color get assigned specifically to NaNs.


Try this function with:

a=peaks;
a(a < 0.5) = nan;
imagescwithnan(a,hot,[0 1 1]) %# [0 1 1] is cyan

test image - NaN color is hidden

If you comment the ylim statement in the function (can be control with additional parameter) this NaN color will be on the colormap.

test image - NaN color is shown on the colorbar

Upvotes: 16

John Colby
John Colby

Reputation: 22588

There are 2 general steps to using multiple color maps like this:

  1. Stack the new colormap with your old one.
  2. Shift the new values that you want to map to this new colormap so that the ratio of range(new data) to range(old data) is the same as nrow(new colormap) to nrow(old colormap).

This will successfully map the new data to the new colormap, while at the same time mapping the old data to the old colormap (i.e. not altering the colors of the old data). Also note that a copy of the data gets stored with the image, so we can do this shifting without altering the original values.

A simplified example:

% Make image data
img = -5:5;

% Plot with original colormap
figure
imagesc(img);
colormap(hot(8))

% Add in an NaN
img(3) = NaN;

% Make new colormap
n = 8;
cols = [0 0 1 %blue
        hot(n)];

% Plot with new colormap
figure
h = imagesc(img);
colormap([0 0 1; hot(8)])

% Scale data so that the range proportions match the colormap sizes
cdata = get(h, 'CData');
img_range = range(cdata(:));
cdata(isnan(cdata)) = min(cdata(:)) - img_range/n;
set(h, 'CData', cdata);

enter image description here

enter image description here

Upvotes: 2

Related Questions