/[MITgcm]/MITgcm_contrib/gael/matlab_class/gcmfaces_misc/imagescnan.m
ViewVC logotype

Annotation of /MITgcm_contrib/gael/matlab_class/gcmfaces_misc/imagescnan.m

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1 - (hide annotations) (download)
Wed Feb 10 14:47:46 2010 UTC (15 years, 5 months ago) by gforget
Branch: MAIN
CVS Tags: checkpoint65x, checkpoint65r, checkpoint65p, checkpoint65q, checkpoint65v, checkpoint65w, checkpoint65t, checkpoint65u, checkpoint66f, checkpoint66e, checkpoint66d, checkpoint66c, checkpoint66b, checkpoint66a, checkpoint66o, HEAD
matlab_class: miscellaneous routines

1 gforget 1.1 function [H,HNAN] = imagescnan(varargin)
2     %IMAGESCNAN Scale data and display as image with uncolored NaNs.
3     %
4     % SYNTAX:
5     % imagescnan(U)
6     % imagescnan(U,...,'NanColor',CNAN)
7     % imagescnan(U,...,'NanMask',MNAN)
8     % imagescnan(U,...,IOPT)
9     % imagescnan(X,Y,U,...)
10     % [H,HNAN] = imagescnan(...);
11     %
12     % INPUT:
13     % U - 2 dimensional N-by-M image or N-by-M-by-3 RGB image.
14     % X - 2 extrema X-axis data; or the M values; or the N-by-M values
15     % as obtained from MESHGRID (see DESCRIPTION below).
16     % DEFAULT: [1 N]
17     % Y - 2 extrema X-axis data; or the N values; or the N-by-M values
18     % as obtained from MESHGRID (see DESCRIPTION below).
19     % DEFAULT: [1 M]
20     % CNAN - Color for the NaNs elements. May be a char specifier or an [R
21     % G B] triplet specifying the color.
22     % DEFAULT: invisible (axes background color)
23     % MNAN - Elements to be ignored besides not finite values. May be an
24     % scalar or a logical M-by-N matrix indicating the elements to
25     % be ignored.
26     % DEFAULT: []
27     % IOPT - IMAGE function normal optional pair arguments like
28     % ('Parent',H) or/and CLIM like optional last argument as in
29     % IMAGESC.
30     % DEFAULT: none
31     %
32     % OUTPUT (all optional):
33     % H - Image handle
34     % HNAN - Handle of every ignored (NaN) value colored patch.
35     %
36     % DESCRIPTION:
37     % MATLAB function IMAGESC does not work properly with NaNs. This
38     % programs deals with this problem by including colored patches over
39     % this elements and maybe others specyfied by the user with MNAN.
40     %
41     % Besides, those functions does not work properly with X,Y values
42     % variable interval, but this functions does it by generating a whole
43     % new image of several rectangular patches, but whose centers may not
44     % lay in the specified coordinate (see NOTE below). This functionality
45     % is experimental and not recommended (see ADDITIONAL NOTES inside this
46     % program).
47     %
48     % In previous release, 2-dim input images were transformed into a
49     % 3-dim RGB image. This is not used anymore (see ADDITIONAL NOTES
50     % inside this file).
51     %
52     % NOTE:
53     % * Optional inputs use its DEFAULT value when not given or [].
54     % * Optional outputs may or not be called.
55     % * If X is a two element vector, min(X) will be the coordinate of the
56     % first column and max(X) of the last column.
57     % * If Y is a two element vector, min(Y) will be the coordinate of the
58     % first row and max(Y) of the last row.
59     % * If vector X-axis is decreasing U=fliplr(U) will be used.
60     % * If vector Y-axis is decreasing U=flipud(U) will be used.
61     % * When X or Y do not have a constant increasing/decreasing step, the
62     % vertices of the color rectangules are set in the middle of each
63     % pair of coordinates. For this reason its center may not lay on the
64     % specified coordinate, except on the coordinates at the edges where
65     % it always lays on the center.
66     % * To get a non-scaled image (IMAGE instead of IMAGESC) use:
67     % >> H = imagescnan(...);
68     % >> set(H,'CDataMapping','direct')
69     % * ADDITIONAL NOTES are included inside this file.
70     %
71     % EXAMPLE:
72     % % Compares with normal IMAGESC:
73     % N = 100;
74     % PNaNs = 0.10;
75     % U = peaks(N);
76     % U(round(1 + (N^2-1).*rand(N^2*PNaNs,1))) = NaN; % Adds NaNs
77     % subplot(221), imagesc(U)
78     % title('With IMAGESC: ugly NaNs')
79     % subplot(222), imagescnan(U)
80     % title('With IMAGESCNAN: uncolored NaNs')
81     % % Compares with SPY:
82     % subplot(223), spy(isnan(U))
83     % title('SPY(isnan(U))')
84     % subplot(224), imagescnan(isnan(U),'NaNMask',0), axis equal tight
85     % title('SPY with IMAGESCNAN')
86     %
87     % SEE ALSO:
88     % IMAGE, IMAGESC, COLORBAR, IMREAD, IMWRITE
89     % and
90     % CMAPPING, CBFREEZE by Carlos Vargas
91     % at http://www.mathworks.com/matlabcentral/fileexchange
92     %
93     %
94     % ---
95     % MFILE: imagescnan.m
96     % VERSION: 2.1 (Aug 20, 2009) (<a href="matlab:web('http://www.mathworks.com/matlabcentral/fileexchange/authors/11258')">download</a>)
97     % MATLAB: 7.7.0.471 (R2008b)
98     % AUTHOR: Carlos Adrian Vargas Aguilera (MEXICO)
99     % CONTACT: nubeobscura@hotmail.com
100    
101     % ADDITIONAL NOTES:
102     % * I keep getting a kind of BUG with the edges of the patched NaNs. I
103     % added two NOTE inside this program that may fix this problem.
104     % Another way is to convert the intensity matrix U into RGB colors by
105     % using the CMAPPING function, as used by the first version of this
106     % program.
107     % * Besides, if the matrix is too large, sometimes there is an
108     % undocumented failure while drawing the patch NaNs. Is recommended
109     % to use U = cmapping(U,[],'k','discrete') instead, and change the
110     % CLIM to [min(U(:)) max(U(:))].
111     % * The use of not homogeneous step interval X,Y axes is not
112     % recommended because the program tries to put its value in the
113     % middle of the colored rectangule (as IMAGESC does) and soetimes the
114     % result may not be what the user wants. So this is for experimental
115     % use only.
116    
117     % REVISIONS:
118     % 1.0 Released. (Jun 30, 2008)
119     % 1.1 Fixed bug when CAXIS used. Colorbar freezed colormap. Fixed
120     % bug in color vector input (Found by Greg King) and now
121     % accets RGB image as input. (Jul 14, 2008)
122     % 2.0 Totally rewritten code. Do not converts to RGB anymore. Do not
123     % freezes the colormap anymore. Do not output any colorbar. New
124     % X and Y variable steps accepted input. Now uses patches. (Jun
125     % 08, 2009)
126     % 2.1 Fixed bug with RGB input. Added a NOTE about the use of
127     % CMAPPING. (Aug 20, 2009)
128    
129     % DISCLAIMER:
130     % imagescnan.m is provided "as is" without warranty of any kind, under
131     % the revised BSD license.
132    
133     % Copyright (c) 2008,2009 Carlos Adrian Vargas Aguilera
134    
135    
136     % INPUTS CHECK-IN
137     % -------------------------------------------------------------------------
138    
139     % Initializes:
140     X = [];
141     Y = [];
142     CNAN = [];
143     MNAN = [];
144     ha = [];
145    
146     % Checks number of inputs:
147     if nargin<1
148     error('CVARGAS:imagescnan:notEnoughInputs',...
149     'At least 1 input is required.')
150     elseif nargout>2
151     error('CVARGAS:imagescnan:tooManyOutputs',...
152     'At most 2 outputs are allowed.')
153     end
154    
155     % Gets X,Y,U:
156     if ((nargin==1) || (nargin==2))
157     U = varargin{1};
158     varargin(1) = [];
159     else
160     if (isnumeric(varargin{1}) && isnumeric(varargin{2}) && ...
161     isnumeric(varargin{3}))
162     X = varargin{1};
163     Y = varargin{2};
164     U = varargin{3};
165     varargin(1:3) = [];
166     else
167     U = varargin{1};
168     varargin(1) = [];
169     end
170     end
171    
172     % Check U:
173     ndim = ndims(U);
174     if (ndim==2)
175     [M,N] = size(U);
176     O = 1;
177     elseif (ndim==3)
178     [M,N,O] = size(U);
179     if (O~=3)
180     error('CVARGAS:imagescnan:incorrectRgbImage',...
181     'RGB image must be of size M-by-N-by-3.')
182     end
183     else
184     error('CVARGAS:imagescnan:incorrectImageSize',...
185     'Image must be 2-dimensional or a 3-dim RGB image.')
186     end
187    
188     % Check X:
189     aequal = true; % Equal intervals on x-axis?
190     dX = [];
191     if isempty(X)
192     X = [1 N];
193     else
194     if (ndims(X)>2)
195     error('CVARGAS:imagescnan:incorrectXDims',...
196     'X must be a vector or a matrix as a result of MESHGRID.')
197     end
198     if any(~isfinite(X(:)))
199     error('CVARGAS:imagescnan:incorrectXValue',...
200     'X elements must be numeric and finite.')
201     end
202     [Mx,Nx] = size(X);
203     if ((Mx*Nx)==2)
204     if X(2)<X(1)
205     X = X([2 1]);
206     for k = 1:O % Fixed bug Aug 2009
207     U(:,:,k) = fliplr(U(:,:,k));
208     end
209     end
210     else
211     if ((Mx==M) && (Nx==N))
212     % Checks if generated with MESHGRID:
213     dX = abs(X(2:M,:)-repmat(X(1,:),M-1,1));
214     if any(abs(dX(:))>(eps*max(abs(dX(:)))*1000))
215     error('CVARGAS:imagescnan:incorrectXMatrix',...
216     'X matrix must be as generated by MESHGRID.')
217     end
218     X = X(1,:);
219     elseif (~any([Mx Nx]==1) && ~((Mx*Nx)==N))
220     error('CVARGAS:imagescnan:incorrectXSize',...
221     'X must be an scalar or a matrix.')
222     end
223     % Forces ascending x-axis:
224     [X,I] = sort(X(:).');
225     for k = 1:O % Fixed bug Aug 2009
226     U(:,:,k) = U(:,I,k);
227     end
228     clear I
229     % Checks equal intervals:
230     dX = diff(X);
231     if any(abs(dX(1)-dX(2:end))>(eps*max(dX)*1000))
232     if aequal
233     aequal = false;
234     end
235     else
236     X = [X(1) X(end)];
237     dX = [];
238     end
239     end
240     end
241    
242     % Check Y:
243     dY = [];
244     if isempty(Y)
245     Y = [1 M];
246     else
247     if (ndims(Y)>2)
248     error('CVARGAS:imagescnan:incorrectYDims',...
249     'Y must be a vector or a matrix as a result of MESHGRID.')
250     end
251     if any(~isfinite(Y(:)))
252     error('CVARGAS:imagescnan:incorrectYValue',...
253     'Y elements must be numeric and finite.')
254     end
255     [My,Ny] = size(Y);
256     if ((My*Ny)==2)
257     if Y(2)<Y(1)
258     Y = Y([2 1]);
259     for k = 1:O % Fixed bug Aug 2009
260     U(:,:,k) = flipud(U(:,:,k));
261     end
262     end
263     else
264     if ((My==M) && (Ny==N))
265     % Checks if generated with MESHGRID:
266     dY = abs(Y(:,2:N)-repmat(Y(:,1),1,N-1));
267     if any(abs(dY(:))>(eps*max(abs(dY(:)))*1000))
268     error('CVARGAS:imagescnan:incorrectYMatrix',...
269     'Y matrix must be as generated by MESHGRID.')
270     end
271     Y = Y(:,1);
272     elseif (~any([My Ny]==1) && ~((My*Ny)==M))
273     error('CVARGAS:imagescnan:incorrectYSize',...
274     'Y must be an scalar or a matrix.')
275     end
276     % Forces ascending y-axis:
277     [Y,I] = sort(Y(:).');
278     for k = 1:O % Fixed bug Aug 2009
279     U(:,:,k) = U(I,:,k);
280     end
281     clear I
282     % Checks equal intervals:
283     dY = diff(Y);
284     if any(abs(dY(1)-dY(2:end))>(eps*max(dY)*1000))
285     if aequal
286     aequal = false;
287     end
288     else
289     Y = [Y(1) Y(end)];
290     dY = [];
291     end
292     end
293     end
294    
295     % Checks varargin:
296     ind = [];
297     Nopt = length(varargin);
298     for k = 1:Nopt-1
299     if (~isempty(varargin{k}) && ischar(varargin{k}))
300     if strncmpi(varargin{k},'NanColor',4)
301     CNAN = varargin{k+1};
302     ind = [ind k k+1];
303     elseif strncmpi(varargin{k},'NanMask',4)
304     MNAN = varargin{k+1};
305     ind = [ind k k+1];
306     elseif (strncmpi(varargin{k},'Parent',2) && isempty(CNAN))
307     try
308     CNAN = get(varargin{k+1},'Color');
309     ha = varargin{k+1};
310     catch
311     error('CVARGAS:imagescnan:incorrectParentHandle',...
312     '''Parent'' must be a valid axes handle.')
313     end
314     end
315     end
316     end
317     varargin(ind) = [];
318     Nargin = length(varargin);
319    
320     % Check ha:
321     if isempty(ha)
322     ha = gca;
323     end
324    
325     % Check CNAN:
326     if isempty(CNAN)
327     CNAN = get(ha,'Color');
328     elseif ischar(CNAN)
329     switch lower(CNAN)
330     case 'y', CNAN = [1 1 0];
331     case 'm', CNAN = [1 0 0];
332     case 'c', CNAN = [0 1 1];
333     case 'r', CNAN = [1 0 0];
334     case 'g', CNAN = [0 1 0];
335     case 'b', CNAN = [0 0 1];
336     case 'w', CNAN = [1 1 1];
337     case 'k', CNAN = [0 0 0];
338     otherwise
339     error('CVARGAS:imagescnan:incorrectNancString',...
340     'Color string must be a valid color identifier. One of ''ymcrgbwk''.')
341     end
342     elseif isnumeric(CNAN) && (length(CNAN)==3)
343     CNAN = CNAN(:).'; % Forces row vector.
344     else
345     error('CVARGAS:imagescnan:incorrectNancInput',...
346     'Not recognized CNAN input.')
347     end
348    
349     % Check MNAN:
350     if isempty(MNAN)
351     MNAN = any(~isfinite(U),3);
352     else
353     if (ndims(MNAN)==2)
354     [Mm,Nm] = size(MNAN);
355     if ((Mm*Nm)==1)
356     MNAN = (any(~isfinite(U),3) | any(U==MNAN,3));
357     elseif ((Mm==M) && (Nm==N) && islogical(MNAN))
358     MNAN = (any(~isfinite(U),3) | MNAN);
359     else
360     error('CVARGAS:imagescnan:incorrectNanmSize',...
361     'MNAN must be an scalar or a logical matrix of size M-by-N.')
362     end
363     else
364     error('CVARGAS:imagescnan:incorrectNanmDims',...
365     'MNAN must be an scalar or a matrix.')
366     end
367     end
368    
369     % -------------------------------------------------------------------------
370     % MAIN
371     % -------------------------------------------------------------------------
372    
373     % Generates the image:
374     if aequal
375     % IMAGESC way.
376     H = imagesc(X,Y,U,varargin{:});
377    
378     else
379     % PATCH way.
380    
381     % Check clim:
382     if (rem(Nargin,2)==1)
383     clim = varargin{end};
384     varargin(end) = [];
385     if ((length(clim)~=2) || (clim(1)>clim(2)))
386     error('CVARGAS:imagescnan:incorrectClimInput',...
387     'clim must be a 2 element increasing vector.')
388     end
389     else
390     clim = [];
391     end
392    
393     % Generates vertices between coordinates (coordinates may not be at the
394     % center of these vertices):
395     if (length(X)~=N)
396     X = (0:N-1)*((X(2)-X(1))/(N-1)) + X(1);
397     end
398     if (length(Y)~=M)
399     Y = (0:M-1)*((Y(2)-Y(1))/(M-1)) + Y(1);
400     end
401     if isempty(dX)
402     dX = diff(X);
403     end
404     if isempty(dY)
405     dY = diff(Y);
406     end
407     [X,Y] = meshgrid([X(1)-dX(1)/2 X+dX([1:N-1 N-1])/2],...
408     [Y(1)-dY(1)/2 Y+dY([1:M-1 M-1])/2]);
409    
410     % Generates faces:
411     ind = (1:(M+1)*N)';
412     ind(M+1:M+1:end) = [];
413    
414     % Generates patches:
415     H = patch(...
416     'Vertices' ,[X(:) Y(:)],...
417     'Faces' ,[ind ind+1 ind+M+2 ind+M+1],...
418     'FaceVertexCData',U(:),...
419     'FaceColor' ,'flat',...
420     'EdgeColor' ,'none',... % NOTE: Sometimes this is not required.
421     varargin{:});
422     set(ha,...
423     'YDir' ,'reverse',...
424     'View' ,[0 90],...
425     'Box' ,'on',...
426     'Layer','top')
427     axis(ha,'tight')
428    
429     % Sets clim:
430     if ~isempty(clim)
431     set(ha,'CLim',clim)
432     else
433     set(ha,'CLimMode','auto')
434     end
435    
436     end
437    
438     % Adds NaNs patches:
439     if any(MNAN(:))
440     if aequal
441     % dX and dY is constant:
442     [MNAN,NNAN] = ind2sub([M,N],find(MNAN));
443     Nnan = length(MNAN);
444     dX = (X(2)-X(1))/(N-1)/2;
445     dY = (Y(2)-Y(1))/(M-1)/2;
446     HNAN = patch(repmat((X(1)+(NNAN(:)'-1)*(2*dX)),4,1) + ...
447     (repmat([-1 1 1 -1]'*dX,1,Nnan)),...
448     repmat((Y(1)+(MNAN(:)'-1)*(2*dY)),4,1) + ...
449     (repmat([1 1 -1 -1]'*dY,1,Nnan)),...
450     CNAN,...
451     'EdgeColor',CNAN,... 'EdgeColor','none',...
452     varargin{1:Nargin-rem(Nargin,2)});
453     else
454     % dX and/or dY is not constant:
455     MNAN = find(MNAN);
456     HNAN = patch(...
457     'Vertices' ,[X(:) Y(:)],...
458     'Faces' ,[ind(MNAN) ind(MNAN)+1 ind(MNAN)+M+2 ind(MNAN)+M+1],...
459     'FaceColor' ,CNAN,...
460     'EdgeColor' ,'none',... 'EdgeColor',CNAN,... % NOTE: may be better?
461     varargin{:});
462     end
463     else
464     HNAN = [];
465     end
466    
467    
468     % OUTPUTS CHECK-OUT
469     % -------------------------------------------------------------------------
470    
471     % Clears outputs?:
472     if (nargout==0)
473     clear H
474     end
475    
476    
477     % [EOF] imagescnan.m

  ViewVC Help
Powered by ViewVC 1.1.22