1 |
function hcb=colorbarf(cout,H,loc) |
---|
2 |
% COLORBARF Display color bar for a filled contour plot. |
---|
3 |
% ========================================================================= |
---|
4 |
% colorbarf Version 1.3 11-Mar-1999 |
---|
5 |
% |
---|
6 |
% Usage: |
---|
7 |
% colorbarf(cout,H,[loc]) |
---|
8 |
% |
---|
9 |
% Description: |
---|
10 |
% This Matlab function uses the output arguments from the contourf function |
---|
11 |
% to produce a colorbar that sets the tick marks equal to the contour levels |
---|
12 |
% in the figure. The area of the colorbar between the tick marks is filled |
---|
13 |
% with the same color used by the contourf function. The location may be |
---|
14 |
% specified as either 'vert' or 'horiz'. |
---|
15 |
% |
---|
16 |
% Input: |
---|
17 |
% cout - output argument of contourf containing an matrix describing the |
---|
18 |
% contours |
---|
19 |
% H - graphics handles for the contours in the figure |
---|
20 |
% loc - location of the colorbar specified 'vert' for vertical (Default) and |
---|
21 |
% 'horiz' for horizontal. If not specified, default is set. |
---|
22 |
% |
---|
23 |
% Output: |
---|
24 |
% hcb - graphics handle for the colorbar axis |
---|
25 |
% |
---|
26 |
% Calls: none |
---|
27 |
% |
---|
28 |
% Author: |
---|
29 |
% Blair Greenan |
---|
30 |
% Bedford Institute of Oceanography |
---|
31 |
% December 22, 1998 |
---|
32 |
% Matlab 5.2.1 |
---|
33 |
% greenanb@mar.dfo-mpo.gc.ca |
---|
34 |
% ========================================================================= |
---|
35 |
% |
---|
36 |
|
---|
37 |
% This function has been derived from the Matlab colorbar function |
---|
38 |
% Author: Clay M. Thompson 10-9-92 |
---|
39 |
% Copyright (c) 1984-98 by The MathWorks, Inc. |
---|
40 |
% $Revision: 5.27 $ $Date: 1997/12/18 17:04:01 $ |
---|
41 |
% |
---|
42 |
|
---|
43 |
% Modifications: |
---|
44 |
% Version 1.1 - function now works with the output of the Matlab |
---|
45 |
% contourf function. Colorbarf can now handle situations in which |
---|
46 |
% the lowest contour level is not filled if an array, which does not |
---|
47 |
% include a value at or below the minimum of the data, is passed to |
---|
48 |
% the contourf function. Version 1.0 also did not plot the colorbar |
---|
49 |
% appropriately if a colorbar already existed on the figure...this |
---|
50 |
% is now fixed. |
---|
51 |
% Version 1.2 - ch.UserData changed to ch(i).UserData. This enables |
---|
52 |
% colrbarf to be used on multiple plot figures - Thanks to Peter Brickley, U. of Maine |
---|
53 |
% Version 1.3 - changes made to handle NaNs in data - 11-Mar-1999 - Thanks to J. van der Molen |
---|
54 |
|
---|
55 |
|
---|
56 |
% If called with COLORBAR(H) or for an existing colorbar, don't change |
---|
57 |
% the NextPlot property. |
---|
58 |
changeNextPlot = 1; |
---|
59 |
|
---|
60 |
% colorbar must have output parameters from the contourf function |
---|
61 |
if (nargin < 2) |
---|
62 |
error('colorbarf requires a minimum of two input parameters'); |
---|
63 |
end |
---|
64 |
|
---|
65 |
% default location for colorbar |
---|
66 |
if nargin<3, loc = 'vert'; end |
---|
67 |
|
---|
68 |
% if an axes handle is passed for the location |
---|
69 |
ax = []; |
---|
70 |
if nargin==3, |
---|
71 |
if ishandle(loc) |
---|
72 |
ax = loc; |
---|
73 |
if ~strcmp(get(ax,'type'),'axes'), |
---|
74 |
error('Requires axes handle.'); |
---|
75 |
end |
---|
76 |
units = get(ax,'units'); set(ax,'units','pixels'); |
---|
77 |
rect = get(ax,'position'); set(ax,'units',units) |
---|
78 |
if rect(3) > rect(4), loc = 'horiz'; else loc = 'vert'; end |
---|
79 |
changeNextPlot = 0; |
---|
80 |
end |
---|
81 |
end |
---|
82 |
|
---|
83 |
h = gca; |
---|
84 |
|
---|
85 |
if (nargin == 2) |
---|
86 |
% Search for existing colorbar so that we can plot over it if we find it |
---|
87 |
ch = get(findobj(gcf,'type','axes','tag','Colorbar')); ax = []; |
---|
88 |
for i=1:length(ch), |
---|
89 |
ud = ch(i).UserData; % ch.UserData changed to ch(i).UserData - suggested by P. Brickley |
---|
90 |
d = ud.PlotHandle; |
---|
91 |
if prod(size(d))==1 & isequal(d,h), |
---|
92 |
ax = findobj(gcf,'type','axes','tag','Colorbar'); |
---|
93 |
pos = ch.Position; |
---|
94 |
if pos(3)<pos(4), loc = 'vert'; else loc = 'horiz'; end |
---|
95 |
changeNextPlot = 0; |
---|
96 |
break; |
---|
97 |
end |
---|
98 |
end |
---|
99 |
elseif ((nargin == 3) & (~ishandle(loc))) |
---|
100 |
% Search for existing colorbar so that we can plot over it if we find it |
---|
101 |
ch = get(findobj(gcf,'type','axes','tag','Colorbar')); ax = []; |
---|
102 |
for i=1:length(ch), |
---|
103 |
ud = ch(i).UserData; % ch.UserData changed to ch(i).UserData - suggested by P. Brickley |
---|
104 |
d = ud.PlotHandle; |
---|
105 |
if prod(size(d))==1 & isequal(d,h), |
---|
106 |
ax = findobj(gcf,'type','axes','tag','Colorbar'); |
---|
107 |
pos = ch.Position; |
---|
108 |
if pos(3)<pos(4), loc = 'vert'; else loc = 'horiz'; end |
---|
109 |
changeNextPlot = 0; |
---|
110 |
break; |
---|
111 |
end |
---|
112 |
end |
---|
113 |
end |
---|
114 |
|
---|
115 |
origNextPlot = get(gcf,'NextPlot'); |
---|
116 |
if strcmp(origNextPlot,'replacechildren') | strcmp(origNextPlot,'replace'), |
---|
117 |
set(gcf,'NextPlot','add') |
---|
118 |
end |
---|
119 |
|
---|
120 |
%%%%%%%%%%%%%% Filled Colorbar %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
---|
121 |
% Blair Greenan Dec 16, 1998 |
---|
122 |
|
---|
123 |
% strip out the information about the contours from the output of the contourf |
---|
124 |
% function |
---|
125 |
i = 1; |
---|
126 |
while ~isempty(cout) |
---|
127 |
C1(i) = cout(1,1); % contour level |
---|
128 |
N1 = cout(2,1); % number of points in contour |
---|
129 |
cout(:,1) = []; % shrink the matrix |
---|
130 |
for j = 1:N1 |
---|
131 |
cout(:,1) = []; % shrink the matrix |
---|
132 |
end |
---|
133 |
i = i + 1; |
---|
134 |
end |
---|
135 |
C2 = unique(C1); % find the unique contour levels and sort |
---|
136 |
numLevels = length(C2); |
---|
137 |
|
---|
138 |
for j = 1:length(H) |
---|
139 |
colors(j) = get(H(j),'CData'); % get the color used to fill the patches |
---|
140 |
end |
---|
141 |
colors = unique(colors); % create a list of unique colors used in fills |
---|
142 |
minc = min(colors); |
---|
143 |
maxc = max(colors); |
---|
144 |
colors(isnan(colors))=[]; |
---|
145 |
if ((length(colors)-numLevels)>1) |
---|
146 |
% chop off extra colors that don't have a corresponding contour level |
---|
147 |
colors(1:((length(colors)-numLevels)-1))=[]; |
---|
148 |
end |
---|
149 |
% special case where no mimima is enclosed by a contour |
---|
150 |
if (length(colors) == numLevels) |
---|
151 |
colors(length(colors)+1)=NaN; |
---|
152 |
end |
---|
153 |
|
---|
154 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
---|
155 |
|
---|
156 |
if loc(1)=='v', % Append vertical scale to right of current plot |
---|
157 |
|
---|
158 |
if isempty(ax), |
---|
159 |
units = get(h,'units'); set(h,'units','normalized') |
---|
160 |
pos = get(h,'Position'); |
---|
161 |
[az,el] = view; |
---|
162 |
stripe = 0.075; edge = 0.02; |
---|
163 |
if all([az,el]==[0 90]), space = 0.05; else space = .1; end |
---|
164 |
set(h,'Position',[pos(1) pos(2) pos(3)*(1-stripe-edge-space) pos(4)]) |
---|
165 |
rect = [pos(1)+(1-stripe-edge)*pos(3) pos(2) stripe*pos(3) pos(4)]; |
---|
166 |
ud.origPos = pos; |
---|
167 |
|
---|
168 |
% Create axes for stripe and |
---|
169 |
% create DeleteProxy object (an invisible text object in |
---|
170 |
% the target axes) so that the colorbar will be deleted |
---|
171 |
% properly. |
---|
172 |
ud.DeleteProxy = text('parent',h,'visible','off',... |
---|
173 |
'tag','ColorbarDeleteProxy',... |
---|
174 |
'handlevisibility','off',... |
---|
175 |
'deletefcn','eval(''delete(get(gcbo,''''userdata''''))'','''')'); |
---|
176 |
ax = axes('Position', rect,'Tag','TMW_COLORBAR'); |
---|
177 |
set(ud.DeleteProxy,'userdata',ax) |
---|
178 |
set(h,'units',units) |
---|
179 |
else % if colobar axes already exist |
---|
180 |
axes(ax); |
---|
181 |
ud = get(ax,'userdata'); |
---|
182 |
end |
---|
183 |
|
---|
184 |
% Create color stripe by drawing the appropriate number of filled rectangles |
---|
185 |
if any(isnan(colors)) % if the bottom level is not filled |
---|
186 |
for j = 1:length(C2)+1 |
---|
187 |
k = j - 1; % don't fill bottom rectangle on colorbar |
---|
188 |
x(1) = 0; |
---|
189 |
x(2) = 1; |
---|
190 |
x(3) = 1; |
---|
191 |
x(4) = 0; |
---|
192 |
y(1) = (j-1)*(1/(length(C2)+1)); |
---|
193 |
y(2) = (j-1)*(1/(length(C2)+1)); |
---|
194 |
y(3) = j*(1/(length(C2)+1)); |
---|
195 |
y(4) = j*(1/(length(C2)+1)); |
---|
196 |
if (k == 0) |
---|
197 |
hfill = fill(x,y,colors(length(colors))); % fill with NaN |
---|
198 |
else |
---|
199 |
hfill = fill(x,y,colors(k)); |
---|
200 |
end |
---|
201 |
hold on |
---|
202 |
end |
---|
203 |
else %we have filled the bottom contour level |
---|
204 |
for j = 1:length(C2)+1 |
---|
205 |
x(1) = 0; |
---|
206 |
x(2) = 1; |
---|
207 |
x(3) = 1; |
---|
208 |
x(4) = 0; |
---|
209 |
y(1) = (j-1)*(1/(length(C2)+1)); |
---|
210 |
y(2) = (j-1)*(1/(length(C2)+1)); |
---|
211 |
y(3) = j*(1/(length(C2)+1)); |
---|
212 |
y(4) = j*(1/(length(C2)+1)); |
---|
213 |
hfill = fill(x,y,colors(j)); |
---|
214 |
hold on |
---|
215 |
end |
---|
216 |
end |
---|
217 |
set(ax,'YAxisLocation','right') |
---|
218 |
set(ax,'xtick',[]) |
---|
219 |
ylimits = get(gca,'ylim'); |
---|
220 |
myYticks = ylimits(1):(ylimits(2)-ylimits(1))/(length(C2)+1):ylimits(2)... |
---|
221 |
-((ylimits(2)-ylimits(1))/(length(C2)+1)); |
---|
222 |
set(gca,'ytick',myYticks); |
---|
223 |
|
---|
224 |
myStr{1} = ' '; |
---|
225 |
for kk = 1:length(C2) |
---|
226 |
myStr{kk+1} = num2str(C2(kk)); |
---|
227 |
end |
---|
228 |
myStr{(length(C2)+2)} = ' '; |
---|
229 |
set(gca,'YTickLabel',myStr) |
---|
230 |
set(gca,'CLim',[minc maxc]) |
---|
231 |
|
---|
232 |
% set up axes deletefcn |
---|
233 |
set(ax,'tag','Colorbar','deletefcn','colorbar(''delete'')') |
---|
234 |
|
---|
235 |
elseif loc(1)=='h', % Append horizontal scale to top of current plot |
---|
236 |
|
---|
237 |
if isempty(ax), |
---|
238 |
units = get(h,'units'); set(h,'units','normalized') |
---|
239 |
pos = get(h,'Position'); |
---|
240 |
stripe = 0.075; space = 0.1; |
---|
241 |
set(h,'Position',... |
---|
242 |
[pos(1) pos(2)+(stripe+space)*pos(4) pos(3) (1-stripe-space)*pos(4)]) |
---|
243 |
rect = [pos(1) pos(2) pos(3) stripe*pos(4)]; |
---|
244 |
ud.origPos = pos; |
---|
245 |
|
---|
246 |
% Create axes for stripe and |
---|
247 |
% create DeleteProxy object (an invisible text object in |
---|
248 |
% the target axes) so that the colorbar will be deleted |
---|
249 |
% properly. |
---|
250 |
ud.DeleteProxy = text('parent',h,'visible','off',... |
---|
251 |
'tag','ColorbarDeleteProxy',... |
---|
252 |
'handlevisibility','off',... |
---|
253 |
'deletefcn','eval(''delete(get(gcbo,''''userdata''''))'','''')'); |
---|
254 |
ax = axes('Position', rect,'Tag','TMW_COLORBAR'); |
---|
255 |
set(ud.DeleteProxy,'userdata',ax) |
---|
256 |
set(h,'units',units) |
---|
257 |
else % if colobar axes already exist |
---|
258 |
axes(ax); |
---|
259 |
ud = get(ax,'userdata'); |
---|
260 |
end |
---|
261 |
|
---|
262 |
% Create color stripe by drawing the appropriate number of filled rectangles |
---|
263 |
if any(isnan(colors)) % if the bottom level is not filled |
---|
264 |
for j = 1:length(C2)+1 |
---|
265 |
k = j - 1; % don't fill bottom rectangle on colorbar |
---|
266 |
y(1) = 0; |
---|
267 |
y(2) = 1; |
---|
268 |
y(3) = 1; |
---|
269 |
y(4) = 0; |
---|
270 |
x(1) = (j-1)*(1/(length(C2)+1)); |
---|
271 |
x(2) = (j-1)*(1/(length(C2)+1)); |
---|
272 |
x(3) = j*(1/(length(C2)+1)); |
---|
273 |
x(4) = j*(1/(length(C2)+1)); |
---|
274 |
if (k == 0) |
---|
275 |
hfill = fill(x,y,colors(length(colors))); % fill with NaN |
---|
276 |
else |
---|
277 |
hfill = fill(x,y,colors(k)); |
---|
278 |
end |
---|
279 |
hold on |
---|
280 |
end |
---|
281 |
else %we have filled the bottom contour level |
---|
282 |
for j = 1:length(C2)+1 |
---|
283 |
y(1) = 0; |
---|
284 |
y(2) = 1; |
---|
285 |
y(3) = 1; |
---|
286 |
y(4) = 0; |
---|
287 |
x(1) = (j-1)*(1/(length(C2)+1)); |
---|
288 |
x(2) = (j-1)*(1/(length(C2)+1)); |
---|
289 |
x(3) = j*(1/(length(C2)+1)); |
---|
290 |
x(4) = j*(1/(length(C2)+1)); |
---|
291 |
hfill = fill(x,y,colors(j)); |
---|
292 |
hold on |
---|
293 |
end |
---|
294 |
end |
---|
295 |
set(ax,'ytick',[]) |
---|
296 |
xlimits = get(gca,'xlim'); |
---|
297 |
myXticks = xlimits(1):(xlimits(2)-xlimits(1))/(length(C2)+1):xlimits(2)... |
---|
298 |
-((xlimits(2)-xlimits(1))/(length(C2)+1)); |
---|
299 |
set(gca,'xtick',myXticks); |
---|
300 |
|
---|
301 |
myStr{1} = ' '; |
---|
302 |
for kk = 1:length(C2) |
---|
303 |
myStr{kk+1} = num2str(C2(kk)); |
---|
304 |
end |
---|
305 |
myStr{(length(C2)+2)} = ' '; |
---|
306 |
set(gca,'XTickLabel',myStr) |
---|
307 |
set(gca,'CLim',[minc maxc]) |
---|
308 |
|
---|
309 |
% set up axes deletefcn |
---|
310 |
set(ax,'tag','Colorbar','deletefcn','colorbar(''delete'')') |
---|
311 |
|
---|
312 |
else |
---|
313 |
error('COLORBAR expects a handle, ''vert'', or ''horiz'' as input.') |
---|
314 |
end |
---|
315 |
|
---|
316 |
if ~isfield(ud,'DeleteProxy'), ud.DeleteProxy = []; end |
---|
317 |
if ~isfield(ud,'origPos'), ud.origPos = []; end |
---|
318 |
ud.PlotHandle = h; |
---|
319 |
set(ax,'userdata',ud) |
---|
320 |
set(gcf,'CurrentAxes',h) |
---|
321 |
set(gcf,'NextPlot',origNextPlot) |
---|
322 |
|
---|
323 |
if nargout>0, hcb = ax; end |
---|