1 |
function handle=thincolorbar(arg1, arg2, arg3) |
2 |
%THINCOLORBAR Display color bar (color scale). |
3 |
% |
4 |
% This is a modification of Matlab's colorbar function that |
5 |
% generates thinner colorbars. |
6 |
% |
7 |
% THINCOLORBAR('vert') appends a vertical color scale to the current |
8 |
% axes. THINCOLORBAR('horiz') appends a horizontal color scale. |
9 |
% |
10 |
% THINCOLORBAR(H) places the thincolorbar in the axes H. |
11 |
% The thincolorbar will be horizontal |
12 |
% if the axes H width > height (in pixels). |
13 |
% |
14 |
% THINCOLORBAR without arguments either adds a new vertical color |
15 |
% scale or updates an existing thincolorbar. |
16 |
% |
17 |
% H = THINCOLORBAR(...) returns a handle to the thincolorbar axes. |
18 |
% |
19 |
% THINCOLORBAR(...,'peer',AX) creates a thincolorbar associated with |
20 |
% axes AXinstead of the current axes. |
21 |
% |
22 |
% See also IMAGESC. |
23 |
|
24 |
% Clay M. Thompson 10-9-92 |
25 |
% Copyright 1984-2002 The MathWorks, Inc. |
26 |
% $Revision: 5.52 $ $Date: 2002/04/08 22:00:12 $ |
27 |
|
28 |
narg = nargin; |
29 |
|
30 |
% when this is done doing whatever it does |
31 |
% gcf and gca should be what they were when we got here |
32 |
% so get them now |
33 |
|
34 |
GCF = gcf; |
35 |
GCA = gca; |
36 |
|
37 |
if narg<2 |
38 |
haxes = gca; |
39 |
hfig = gcf; |
40 |
if narg<1 |
41 |
loc = 'vert'; % Default mode when called without arguments. |
42 |
else |
43 |
% Peer must be followed by a valid axes handle. |
44 |
if strcmp(arg1,'peer') |
45 |
error('Parameter ''peer'' must be followed by an axes handle.'); |
46 |
end |
47 |
loc = arg1; |
48 |
end |
49 |
elseif narg == 2 |
50 |
% This is the case ONLY when peer and a handle is passed. |
51 |
if strcmp(arg1,'peer') |
52 |
if ishandle(arg2) & strcmp(get(arg2, 'type'), 'axes') |
53 |
haxes = arg2; |
54 |
hfig = get(haxes,'parent'); |
55 |
loc = 'vert'; |
56 |
narg = 0; |
57 |
else |
58 |
% If second arg is not a valid axes handle |
59 |
error('Second argument must be a scalar axes handle.'); |
60 |
end |
61 |
else |
62 |
error('Unknown command option.'); |
63 |
end |
64 |
else |
65 |
% For three arguments the first must be the mode or a axes handle, |
66 |
% second must be the string 'peer' and third must be the peer axes handle. |
67 |
loc = arg1; |
68 |
if strcmp(arg2,'peer') |
69 |
if ishandle(arg3) & strcmp(get(arg3, 'type'), 'axes') |
70 |
haxes = arg3; |
71 |
hfig = get(haxes,'parent'); |
72 |
narg = 1; |
73 |
else |
74 |
error('Third argument must be a scalar axes handle.'); |
75 |
end |
76 |
else |
77 |
error('Unknown command option.'); |
78 |
end |
79 |
end |
80 |
|
81 |
% Catch colorbar('delete') special case -- must be called by the deleteFcn. |
82 |
if narg==1 & strcmp(loc,'delete') |
83 |
ax = gcbo; |
84 |
% |
85 |
% If called from ColorbarDeleteProxy, delete the colorbar axes |
86 |
% |
87 |
if strcmp(get(ax,'tag'),'ColorbarDeleteProxy') |
88 |
cbo = ax; |
89 |
ax = get(cbo,'userdata'); |
90 |
if ishandle(ax) |
91 |
ud = get(ax,'userdata'); |
92 |
|
93 |
% Do a sanity check before deleting colorbar |
94 |
if isfield(ud,'ColorbarDeleteProxy') & ... |
95 |
isequal(ud.ColorbarDeleteProxy,cbo) & ... |
96 |
ishandle(ax) |
97 |
try |
98 |
delete(ax) |
99 |
end |
100 |
end |
101 |
end |
102 |
else |
103 |
% |
104 |
% If called from the colorbar image resize the original axes |
105 |
% |
106 |
if strcmp(get(ax,'tag'),'TMW_COLORBAR') |
107 |
ax=get(ax,'parent'); |
108 |
end |
109 |
|
110 |
ud = get(ax,'userdata'); |
111 |
if isfield(ud,'PlotHandle') & ... |
112 |
ishandle(ud.PlotHandle) & ... |
113 |
isfield(ud,'origPos') & ... |
114 |
~isempty(ud.origPos) |
115 |
|
116 |
% Get position and orientation of colorbar being deleted |
117 |
delpos = get(ax,'Position'); |
118 |
if delpos(3)<delpos(4) |
119 |
delloc = 'vert'; |
120 |
else |
121 |
delloc = 'horiz'; |
122 |
end |
123 |
|
124 |
% Search figure for existing colorbars |
125 |
% If one is found with the same plothandle but that is not |
126 |
% the same colorbar as the one being deleted |
127 |
% Get its position and orientation |
128 |
otherloc = ''; |
129 |
otherpos = []; |
130 |
othercbar = []; |
131 |
phch = get(findall(hfig,'type','image','tag','TMW_COLORBAR'),{'parent'}); |
132 |
for i=1:length(phch) |
133 |
phud = get(phch{i},'userdata'); |
134 |
if isfield(ud,'PlotHandle') & isfield(phud,'PlotHandle') |
135 |
if isequal(ud.PlotHandle,phud.PlotHandle) |
136 |
if ~isequal(phch{i},ax) |
137 |
othercbar = phch{i}; |
138 |
otherpos = get(phch{i},'Position'); |
139 |
if otherpos(3)<otherpos(4) |
140 |
otherloc = 'vert'; |
141 |
else |
142 |
otherloc = 'horiz'; |
143 |
end |
144 |
break; |
145 |
end |
146 |
end |
147 |
end |
148 |
end |
149 |
|
150 |
|
151 |
% get the current plothandle units |
152 |
units = get(ud.PlotHandle,'units'); |
153 |
% set plothandle units to normalized |
154 |
set(ud.PlotHandle,'units','normalized'); |
155 |
% get current plothandle position |
156 |
phpos = get(ud.PlotHandle,'position'); |
157 |
|
158 |
% if the colorbar being deleted is vertical |
159 |
% set the plothandle axis width to the original Pos |
160 |
% width of the colorbar being deleted |
161 |
% if there is another (horizontal) colorbar |
162 |
% do the same to that |
163 |
if strncmp(delloc,'vert',1) |
164 |
phpos(3) = ud.origPos(3); |
165 |
set(ud.PlotHandle,'position',phpos); |
166 |
if strncmp(otherloc,'horiz',1) |
167 |
otherpos(3) = ud.origPos(3); |
168 |
set(othercbar,'position',otherpos); |
169 |
end |
170 |
|
171 |
% update legend (which resizes plothandle) |
172 |
% only when deleting vertical colorbars |
173 |
|
174 |
legH=legend(ud.PlotHandle); |
175 |
if ~isempty(legH) & ishandle(legH) |
176 |
% save size of current plothandle axes with legend ud |
177 |
legend('RecordSize',ud.PlotHandle); |
178 |
% resize (reposition) legend |
179 |
legend('ResizeLegend',legH); |
180 |
end |
181 |
|
182 |
% elseif the colorbar being deleted is horizontal |
183 |
% set the plothandle y and height to the original Pos |
184 |
% y and height of the colorbar being deleted. |
185 |
% if there is another (vertical) colorbar |
186 |
% do the same to that |
187 |
elseif strncmp(delloc,'horiz',1) |
188 |
phpos(4) = ud.origPos(4); |
189 |
phpos(2) = ud.origPos(2); |
190 |
set(ud.PlotHandle,'position',phpos); |
191 |
if strncmp(otherloc,'vert',1) |
192 |
otherpos(4) = ud.origPos(4); |
193 |
otherpos(2) = ud.origPos(2); |
194 |
set(othercbar,'position',otherpos); |
195 |
end |
196 |
|
197 |
end |
198 |
|
199 |
% restore the plothandle units |
200 |
set(ud.PlotHandle,'units',units); |
201 |
|
202 |
|
203 |
end |
204 |
|
205 |
if isfield(ud,'ColorbarDeleteProxy') & ishandle(ud.ColorbarDeleteProxy) |
206 |
try |
207 |
delete(ud.ColorbarDeleteProxy) |
208 |
end |
209 |
end |
210 |
end |
211 |
% before going, be sure to reset current figure and axes |
212 |
set(0,'currentfigure',GCF); |
213 |
set(gcf,'currentaxes',GCA); |
214 |
return |
215 |
end |
216 |
|
217 |
% If called with COLORBAR(H) or for an existing colorbar, don't change |
218 |
% the NextPlot property. |
219 |
|
220 |
ax = []; |
221 |
cbarinaxis=0; |
222 |
if narg==1 |
223 |
if ishandle(loc) |
224 |
ax = loc; |
225 |
ud = get(ax,'userdata'); |
226 |
if isfield(ud,'ColorbarDeleteProxy') |
227 |
error('Colorbar cannot be added to another colorbar.') |
228 |
end |
229 |
if ~strcmp(get(ax,'type'),'axes') |
230 |
error('Requires axes handle.'); |
231 |
end |
232 |
|
233 |
cbarinaxis=1; |
234 |
units = get(ax,'units'); |
235 |
set(ax,'units','pixels'); |
236 |
rect = get(ax,'position'); |
237 |
set(ax,'units',units); |
238 |
if rect(3) > rect(4) |
239 |
loc = 'horiz'; |
240 |
else |
241 |
loc = 'vert'; |
242 |
end |
243 |
end |
244 |
end |
245 |
|
246 |
|
247 |
% the axes handle, shorter name |
248 |
h = haxes; |
249 |
|
250 |
% Catch attempt to add colorbar to a colorbar or legend |
251 |
% if the axes h is a colorbar or legend (according to tag) |
252 |
% reset it to the PlotHandle field of its userdata |
253 |
tagstr = get(h,'tag'); |
254 |
if strcmpi('Legend',tagstr) | strcmpi('Colorbar',tagstr) |
255 |
ud = get(h,'userdata'); |
256 |
if isfield(ud,'PlotHandle') |
257 |
h = ud.PlotHandle; |
258 |
else |
259 |
% If handle is a dying or mutant colorbar or legend |
260 |
% do nothing. |
261 |
% but before going, be sure to reset current figure and axes |
262 |
set(0,'currentfigure',GCF); |
263 |
set(gcf,'currentaxes',GCA); |
264 |
return; |
265 |
end |
266 |
end |
267 |
|
268 |
% Determine color limits by context. If any axes child is an image |
269 |
% use scale based on size of colormap, otherwise use current CAXIS. |
270 |
|
271 |
ch = get(gcda(hfig,h),'children'); |
272 |
hasimage = 0; t = []; |
273 |
cdatamapping = 'direct'; |
274 |
|
275 |
for i=1:length(ch), |
276 |
typ = get(ch(i),'type'); |
277 |
if strcmp(typ,'image'), |
278 |
hasimage = 1; |
279 |
cdatamapping = get(ch(i), 'CDataMapping'); |
280 |
elseif strcmp(typ,'surface') & ... |
281 |
strcmp(get(ch(i),'FaceColor'),'texturemap') % Texturemapped surf |
282 |
hasimage = 2; |
283 |
cdatamapping = get(ch(i), 'CDataMapping'); |
284 |
elseif strcmp(typ,'patch') | strcmp(typ,'surface') |
285 |
cdatamapping = get(ch(i), 'CDataMapping'); |
286 |
end |
287 |
end |
288 |
|
289 |
if ( strcmp(cdatamapping, 'scaled') ) |
290 |
% Treat images and surfaces alike if cdatamapping == 'scaled' |
291 |
t = caxis(h); |
292 |
d = (t(2) - t(1))/size(colormap(h),1); |
293 |
t = [t(1)+d/2 t(2)-d/2]; |
294 |
else |
295 |
if hasimage, |
296 |
t = [1, size(colormap(h),1)]; |
297 |
else |
298 |
t = [1.5 size(colormap(h),1)+.5]; |
299 |
end |
300 |
end |
301 |
|
302 |
oldloc = 'none'; |
303 |
oldax = []; |
304 |
if ~cbarinaxis |
305 |
% Search for existing colorbar (parents of TMW_COLORBAR tagged images) |
306 |
ch = get(findall(hfig,'type','image','tag','TMW_COLORBAR'),{'parent'}); |
307 |
ax = []; |
308 |
for i=1:length(ch) |
309 |
ud = get(ch{i},'userdata'); |
310 |
d = ud.PlotHandle; |
311 |
% if the plothandle (axis) of the colorbar is our axis |
312 |
if isequal(d,h) |
313 |
pos = get(ch{i},'Position'); |
314 |
if pos(3)<pos(4) |
315 |
oldloc = 'vert'; |
316 |
else |
317 |
oldloc = 'horiz'; |
318 |
end |
319 |
% set ax to the ith colorbar |
320 |
% if it's location (orientation) is the same as the |
321 |
% new colorbar location (so a second colorbar with |
322 |
% the same orientation won't be created, and existing |
323 |
% colorbar will be updated |
324 |
if strncmp(oldloc,loc,1) |
325 |
ax = ch{i}; |
326 |
% Make sure image deletefcn doesn't trigger a colorbar('delete') |
327 |
% for colorbar update - huh? |
328 |
set(findall(ax,'type','image'),'deletefcn','') |
329 |
break; |
330 |
end |
331 |
end |
332 |
end |
333 |
end |
334 |
|
335 |
origNextPlot = get(hfig,'NextPlot'); |
336 |
if strcmp(origNextPlot,'replacechildren') | strcmp(origNextPlot,'replace') |
337 |
set(hfig,'NextPlot','add'); |
338 |
end |
339 |
|
340 |
if loc(1)=='v' % create or refresh vertical colorbar |
341 |
|
342 |
if isempty(ax) |
343 |
legend('RestoreSize',h); %restore axes to pre-legend size |
344 |
units = get(h,'units'); |
345 |
set(h,'units','normalized'); |
346 |
pos = get(h,'Position'); |
347 |
[az,el] = view(h); |
348 |
|
349 |
%cdm start modification |
350 |
%cdm stripe = 0.075; edge = 0.02; |
351 |
%cdm if all([az,el]==[0 90]) |
352 |
%cdm space = 0.05; |
353 |
%cdm else |
354 |
%cdm space = .1; |
355 |
%cdm end |
356 |
stripe = 0.025; edge = 0.005; |
357 |
if all([az,el]==[0 90]) |
358 |
space = 0.015; |
359 |
else |
360 |
space = .03; |
361 |
end |
362 |
%cdm end modification |
363 |
|
364 |
set(h,'Position',[pos(1) pos(2) pos(3)*(1-stripe-edge-space) pos(4)]); |
365 |
legend('RecordSize',h); %set this as the new legend fullsize |
366 |
|
367 |
rect = [pos(1)+(1-stripe-edge)*pos(3) pos(2) stripe*pos(3) pos(4)]; |
368 |
ud.origPos = pos; |
369 |
|
370 |
% Create axes for stripe and |
371 |
% create ColorbarDeleteProxy object (an invisible text object in |
372 |
% the target axes) so that the colorbar will be deleted |
373 |
% properly. |
374 |
ud.ColorbarDeleteProxy = text('parent',h,... |
375 |
'visible','off',... |
376 |
'tag','ColorbarDeleteProxy',... |
377 |
'HandleVisibility','off',... |
378 |
'deletefcn','colorbar(''delete'',''peer'',get(gcbf,''currentaxes''))'); |
379 |
|
380 |
axH = graph3d.colorbar('parent',hfig); |
381 |
set(axH,'position',rect,'Orientation','vert'); |
382 |
ax = double(axH); |
383 |
|
384 |
setappdata(ax,'NonDataObject',[]); % For DATACHILDREN.M |
385 |
set(ud.ColorbarDeleteProxy,'userdata',ax) |
386 |
set(h,'units',units) |
387 |
else |
388 |
axH=[]; |
389 |
ud = get(ax,'userdata'); |
390 |
end |
391 |
|
392 |
% Create color stripe |
393 |
n = size(colormap(h),1); |
394 |
|
395 |
img = image([0 1],t,(1:n)',... |
396 |
'Parent',ax,... |
397 |
'Tag','TMW_COLORBAR',... |
398 |
'deletefcn','colorbar(''delete'',''peer'',get(gcbf,''currentaxes''))',... |
399 |
'SelectionHighlight','off',... |
400 |
'HitTest','off'); |
401 |
|
402 |
%set up axes delete function |
403 |
set(ax,... |
404 |
'Ydir','normal',... |
405 |
'YAxisLocation','right',... |
406 |
'xtick',[],... |
407 |
'tag','Colorbar',... |
408 |
'deletefcn','colorbar(''delete'',''peer'',get(gcbf,''currentaxes''))'); |
409 |
|
410 |
|
411 |
elseif loc(1)=='h', % create or refresh horizontal colorbar |
412 |
|
413 |
if isempty(ax), |
414 |
legend('RestoreSize',h); %restore axes to pre-legend size |
415 |
units = get(h,'units'); set(h,'units','normalized') |
416 |
pos = get(h,'Position'); |
417 |
%cdm start modification |
418 |
%cdm stripe = 0.075; space = 0.1; |
419 |
stripe = 0.025; space = 0.05; |
420 |
%cdm end modification |
421 |
set(h,'Position',... |
422 |
[pos(1) pos(2)+(stripe+space)*pos(4) pos(3) (1-stripe-space)*pos(4)]) |
423 |
legend('RecordSize',h); %set this as the new legend fullsize |
424 |
rect = [pos(1) pos(2) pos(3) stripe*pos(4)]; |
425 |
ud.origPos = pos; |
426 |
|
427 |
% Create axes for stripe and |
428 |
% create ColorbarDeleteProxy object (an invisible text object in |
429 |
% the target axes) so that the colorbar will be deleted |
430 |
% properly. |
431 |
ud.ColorbarDeleteProxy = text('parent',h,... |
432 |
'visible','off',... |
433 |
'tag','ColorbarDeleteProxy',... |
434 |
'handlevisibility','off',... |
435 |
'deletefcn','colorbar(''delete'',''peer'',get(gcbf,''currentaxes''))'); |
436 |
|
437 |
axH = graph3d.colorbar('parent',hfig); |
438 |
set(axH,'Orientation','horiz'); |
439 |
set(axH,'position',rect); |
440 |
ax = double(axH); |
441 |
|
442 |
setappdata(ax,'NonDataObject',[]); % For DATACHILDREN.M |
443 |
set(ud.ColorbarDeleteProxy,'userdata',ax) |
444 |
set(h,'units',units) |
445 |
else |
446 |
axH=[]; |
447 |
ud = get(ax,'userdata'); |
448 |
end |
449 |
|
450 |
% Create color stripe |
451 |
n = size(colormap(h),1); |
452 |
img=image(t,[0 1],(1:n),... |
453 |
'Parent',ax,... |
454 |
'Tag','TMW_COLORBAR',... |
455 |
'deletefcn','colorbar(''delete'',''peer'',get(gcbf,''currentaxes''))',... |
456 |
'SelectionHighlight','off',... |
457 |
'HitTest','off'); |
458 |
|
459 |
% set up axes deletefcn |
460 |
set(ax,... |
461 |
'Ydir','normal',... |
462 |
'Ytick',[],... |
463 |
'tag','Colorbar',... |
464 |
'deletefcn','colorbar(''delete'',''peer'',get(gcbf,''currentaxes''))') |
465 |
|
466 |
else |
467 |
error('COLORBAR expects a handle, ''vert'', or ''horiz'' as input.') |
468 |
end |
469 |
|
470 |
if ~isfield(ud,'ColorbarDeleteProxy') |
471 |
ud.ColorbarDeleteProxy = []; |
472 |
end |
473 |
|
474 |
if ~isfield(ud,'origPos') |
475 |
ud.origPos = []; |
476 |
end |
477 |
|
478 |
ud.PlotHandle = h; |
479 |
set(ax,'userdata',ud) |
480 |
set(hfig,'NextPlot',origNextPlot) |
481 |
|
482 |
legH=legend(h); |
483 |
if ~isempty(legH) & ishandle(legH) |
484 |
% resize (reposition) legend |
485 |
legend('ResizeLegend',legH); |
486 |
axes(legH); |
487 |
end |
488 |
|
489 |
%make sure annotation layer ends up on top. |
490 |
plotedit(get(ax,'parent'),'promoteoverlay'); |
491 |
|
492 |
if nargout>0 |
493 |
handle = ax; |
494 |
end |
495 |
|
496 |
% Finally, before going, be sure to reset current figure and axes |
497 |
set(0,'currentfigure',GCF); |
498 |
set(gcf,'currentaxes',GCA); |
499 |
|
500 |
%-------------------------------- |
501 |
function h = gcda(hfig, haxes) |
502 |
%GCDA Get current data axes |
503 |
|
504 |
h = datachildren(hfig); |
505 |
if isempty(h) | any(h == haxes) |
506 |
h = haxes; |
507 |
else |
508 |
h = h(1); |
509 |
end |
510 |
|