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

Contents 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 - (show 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 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