Code covered by the BSD License  

Highlights from
Zerocolor

image thumbnail

Zerocolor

by

 

Set colormap entry for zero values to specified RGB color

zerocolor(varargin)
function varargout = zerocolor(varargin)
%ZEROCOLOR - Set colormap entry for zero value to specified RGB color
%  zerocolor(CLR)
%  updates current figure's colormap so that zeros get color CLR
%  CLR is a vector between 0-1, e.g. [.4 .2 .9] or a standard MATLAB color
%  string shorthand, e.g. 'r'.
%  
%  zerocolor(H,CLR) uses figure handle H instead of current.
%
%  cmap = zerocolor(...)
%  Outputs modified cmap based on figure's colormap.
%  Does not apply it to figure. Apply with colormap().
%
%  cmap = zerocolor(CLR,oldmap,clims)
%  Outputs modified cmap based on oldmap and context data. 
%  may supply data instead of clims, gets [min max] of data to create clims
%
%  --- Examples:
%
% CLR   = [0 1 0];
% 
% % Create Intensity images:
% DATA1 = randi(10,100)-5;  %contains zeros
% DATA2 = DATA1;            
% DATA2(DATA2 > 0) = 0;     %zero is upper bound
% DATA3 = DATA1;
% DATA3(DATA3 < 0) = 0;     %zero is lower bound
% DATA4 = rand(100);        %has no zeros--normally speaking
% DATA5 = imread('peppers.png');
% 
% % Plot:
% h1 = figure; h11=imagesc(DATA1);colormap(hot(10));colorbar; %Clim contains zero
% h2 = figure; h22=imagesc(DATA2);colormap(hot(10));colorbar; %Clim contains zero
% h3 = figure; h33=imagesc(DATA3);colormap(hot(10));colorbar; %Clim contains zero
% h4 = figure; h44=imagesc(DATA4);colormap(hot(10));colorbar; %Contains no explicit zero mapping
% h5 = figure; h55=imshow(DATA5);                             %Not an intensity image
% 
% zerocolor(h1,CLR);
% 
% zerocolor(h2,CLR);
% 
% zerocolor(h3,CLR);
% 
% zerocolor(h4,CLR);
% set(get(h4,'CurrentAxes'),'CLim',[0 1]); %Now h4 does work
% zerocolor(h4,CLR);
% 
% zerocolor(h5,CLR); %Doesn't work with RGB
% 
% cmap = zerocolor([0 0 0],jet(10),[-2 1]); %new jet map with a black entry
%
%  --- Notes:
%  Does nothing with RGB images, only real 2D intensity matrices.
%  Does not do anything if zero value lies outside the mapping range.
%
%  Note this is not the same as changing the first/last color of the map,
%  though that may happen if zero is the first or last indexed value.
%  Probably most useful when data has a range: negative<->positive.
%  Not hard to adjust for an arbitrary value other than zero.
%
%  Inspired by rgbslide from the MATLAB FEX
%
%  ~~~~Jurgen

assert(nargin < 4,'Too many input arguments');
if nargout
    out = true;
else
    out = false;
end

% --- Parse H, CLR, oldmap, clims, data
[H CLR clims oldmap] = parse_args(varargin);

% --- convert shorthand to [R G B]
if ischar(CLR)
    CLR = convert_to_rgb(CLR);
else
    assert(numel(CLR)==3 && length(CLR) ==3,...
    'CLR isn''t a color!')
end

% --- common cases: start/end at zero
if clims(1) == 0
    cmap = oldmap;
    cmap(1,:) = CLR;
    finish
    return
elseif clims(2) == 0
    cmap = oldmap;
    cmap(end,:) = CLR;
    finish
    return         
end

% --- generate new map
zeroidx          = findzeroclr(oldmap,clims);
cmap             = oldmap;
cmap(zeroidx,:)  = CLR;
finish

function finish
    if out
        varargout{1} = cmap;
    else
        colormap(get(H,'CurrentAxes'),cmap)
    end
end  %Nested

end


function zeroidx = findzeroclr(oldmap,clims)
% Assumes CLim range gets linearly quantized when mapping
% Not valid if indexed, only for intensity images.
a = linspace(clims(1),clims(2),size(oldmap,1)+1);
if any(a == 0)
   zeroidx = find(a == 0);
else
   zeroidx = sum(a<0);
end
end

function CLR = convert_to_rgb(CLR)
    switch CLR
        case 'r'
            CLR = [1 0 0];
        case 'c'
            CLR = [0 1 1];            
        case 'y'
            CLR = [1 1 0];            
        case 'm'
            CLR = [1 0 1];            
        case 'g'
            CLR = [0 1 0];            
        case 'b'
            CLR = [0 0 1];            
        case 'k'
            CLR = [0 0 0];            
        case 'w'
            CLR = [1 1 1];            
        otherwise
            error(['Unknown color shorthand: ' CLR]);
    end    
end
        
function [H CLR clims oldmap] = parse_args(args)
nargin = length(args);

if nargin == 2 
    Q = args{1};
    if numel(Q) == 1
        assert(ishandle(Q) && (Q ~= 0) && strcmp(get(Q,'Type'),'figure')...
            ,'Wrong handle for H');
        H   = Q;
        CLR = args{2};
    else
        H   = gcf;
        CLR = Q;
    end    
    clear Q;
elseif nargin == 3
    CLR = args{1};    
else
    H   = gcf;
    CLR = args{1};
end

if nargin ~= 3
    [dum dum dum flag]  = getimage(H);
    
    assert(flag ~= 4,'Can not apply colormaps to RGB images');
    
    oldmap = get(H,'Colormap');
    ax     = get(H,'CurrentAxes');
    clims  = get(ax,'CLim');
    
    assert(isempty(findobj(ax,'CDataMapping','direct','-depth',1)),...
        'Image is indexed, change CDataMapping to ''scaled''');
else
    H = [];
    oldmap = args{2};
    cdata  = args{3};
    clims  = [min(cdata(:)) max(cdata(:))];
end

try
assert(clims(1) <= eps && clims(2) >= -eps)
catch
    display(clims);
    disp(['Failing boundary: ' num2str([(clims(1) <= eps(2)) (clims(2) >= eps(2))])]);
    disp(' ');
    error('parseargs:limitcheck',...
['  CLim Check: No explicit zero value in colormap range!\n'...
'  i.e. zeros are / were being clipped--if they exist at all.\n'...
'  Change CLim property / vector to contain zero']);
end

end
    
    

Contact us