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
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
If you comment the ylim statement in the function (can be control with additional parameter) this NaN color will be on the colormap.
There are 2 general steps to using multiple color maps like this:
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);
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 nan
s by default.
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