comparison scripts/plot/colorbar.m @ 8101:86955a1559c5

improve speed of cell2mat * * * trivial fix for previous cell2mat change
author David Bateman <dbateman@free.fr>
date Thu, 11 Sep 2008 16:57:12 -0400
parents 1b954fdaf4ff
children c066714ee5d5
comparison
equal deleted inserted replaced
8100:da2fbd22d672 8101:86955a1559c5
1 ## Copyright (C) 2007 David Bateman 1 ## Copyright (C) 2008 David Bateman
2 ## 2 ##
3 ## This file is part of Octave. 3 ## This file is part of Octave.
4 ## 4 ##
5 ## Octave is free software; you can redistribute it and/or modify it 5 ## Octave is free software; you can redistribute it and/or modify it
6 ## under the terms of the GNU General Public License as published by 6 ## under the terms of the GNU General Public License as published by
45 ## If the argument 'peer' is given, then the following argument is treated 45 ## If the argument 'peer' is given, then the following argument is treated
46 ## as the axes handle on which to add the colorbar. 46 ## as the axes handle on which to add the colorbar.
47 ## @end deftypefn 47 ## @end deftypefn
48 48
49 49
50 ## PKG_ADD: mark_as_command colorbar 50 function h = colorbar (varargin)
51 51 ax = [];
52 function colorbar (varargin) 52 loc = "eastoutside";
53 53 args = {};
54 if (nargin > 0 && strcmpi(varargin{1}, "peer")) 54 deleting = false;
55 if (nargin > 1) 55
56 ax = varargin{2}; 56 i = 1;
57 if (!isscalar (ax) || ! ishandle (ax) 57 while (i <= nargin)
58 || strcmp (get (ax, "type"), "axes")) 58 arg = varargin {i++};
59 error ("colorbar: expecting an axes handle following 'peer'"); 59
60 endif 60 if (ischar(arg))
61 else 61 if (strcmpi (arg, "peer"))
62 error ("colorbar: misisng axes handle after 'peer'"); 62 if (i > nargin)
63 endif 63 error ("colorbar: missing axes handle after 'peer'");
64 else
65 ax = vargin{i++}
66 if (!isscalar (ax) || ! ishandle (ax)
67 || strcmp (get (ax, "type"), "axes"))
68 error ("colorbar: expecting an axes handle following 'peer'");
69 endif
70 endif
71 elseif (strcmpi (arg, "north") || strcmpi (arg, "south")
72 || strcmpi (arg, "east") || strcmpi (arg, "west")
73 || strcmpi (arg, "northoutside") || strcmpi (arg, "southoutside")
74 || strcmpi (arg, "eastoutside") || strcmpi (arg, "westoutside"))
75 loc = arg;
76 elseif (strcmpi (arg, "off") || strcmpi (arg, "none"))
77 deleting = true;
78 else
79 args{end+1} = arg;
80 endif
81 else
82 args{end+1} = arg;
83 endif
84 endwhile
85
86 if (isempty (ax))
87 ax = gca ();
88 endif
89 obj = get (ax);
90
91 if (deleting)
92 objs = findobj (get (ax, "parent"), "type", "axes");
93 for i = 1 : length (objs)
94 if (strcmp (get (objs(i), "tag"), "colorbar") &&
95 get (objs(i), "axes") == ax)
96 delete (objs(i));
97 endif
98 endfor
64 else 99 else
65 ax = gca (); 100 position = obj.position;
66 endif 101 clen = rows (get (get (ax, "parent"), "colormap"));
67 102 cext = get (ax, "clim");
68 pos = "eastoutside"; 103 cdiff = (cext(2) - cext(1)) / clen / 2;
69 for i = 1 : length (varargin) 104 cmin = cext(1) + cdiff;
70 arg = varargin{i}; 105 cmax = cext(2) - cdiff;
71 if (length(arg) < 1) 106
72 pos = "eastoutside"; 107 orig_pos = obj.position;
73 elseif (ischar (arg)) 108 orig_opos = obj.outerposition;
74 arg = tolower (arg); 109 [pos, cpos, vertical, mirror, aspect] = ...
75 if (strcmp (arg, "off") || strcmp (arg, "none")) 110 __position_colorbox__ (loc, obj, ancestor (ax, "figure"));
76 pos = "none"; 111 set (ax, "activepositionproperty", "position", "position", pos);
77 elseif (strcmp (arg, "north") || strcmp (arg, "south") 112
78 || strcmp (arg, "east") || strcmp (arg, "west") 113 cax = __go_axes__ (get (ax, "parent"), "tag", "colorbar",
79 || strcmp (arg, "northoutside") || strcmp (arg, "southoutside") 114 "handlevisibility", "off",
80 || strcmp (arg, "eastoutside") || strcmp (arg, "westoutside")) 115 "activepositionproperty", "position",
81 pos = arg; 116 "position", cpos);
82 else 117 addproperty ("location", cax, "radio",
83 error ("colorbar: unrecognized position argument"); 118 "eastoutside|east|westoutside|west|northoutside|north|southoutside|south",
84 endif 119 loc);
85 else 120 addproperty ("axes", cax, "handle", ax);
86 error ("colorbar: expecting string arguments"); 121
87 endif 122 if (vertical)
88 endfor 123 hi = image (cax, [0,1], [cmin, cmax], [1 : clen]');
89 124 if (mirror)
90 set (ax, "__colorbar__", pos); 125 set (cax, "xtick", [], "xdir", "normal", "ydir", "normal",
91 126 "ylim", cext, "ylimmode", "manual",
92 endfunction 127 "yaxislocation", "right", args{:});
93 128 else
129 set (cax, "xtick", [], "xdir", "normal", "ydir", "normal",
130 "ylim", cext, "ylimmode", "manual",
131 "yaxislocation", "left", args{:});
132 endif
133 else
134 hi = image (cax, [cmin, cmax], [0,1], [1 : clen]);
135 if (mirror)
136 set (cax, "ytick", [], "xdir", "normal", "ydir", "normal",
137 "xlim", cext, "xlimmode", "manual",
138 "xaxislocation", "top", args{:});
139 else
140 set (cax, "ytick", [], "xdir", "normal", "ydir", "normal",
141 "xlim", cext, "xlimmode", "manual",
142 "xaxislocation", "bottom", args{:});
143 endif
144 endif
145
146 if (! isnan (aspect))
147 set (cax, "dataaspectratio", aspect);
148 endif
149
150 ctext = text (0, 0, "", "tag", "colorbar","visible", "off",
151 "handlevisibility", "off", "xliminclude", "off",
152 "yliminclude", "off", "zliminclude", "off",
153 "deletefcn", {@deletecolorbar, cax, orig_pos, orig_opos});
154
155 set (cax, "deletefcn", {@resetaxis, orig_pos, orig_opos});
156
157 addlistener (ax, "clim", {@update_colorbar_clim, hi, vertical})
158 addlistener (ax, "dataaspectratio", {@update_colorbar_axis, cax})
159 addlistener (ax, "position", {@update_colorbar_axis, cax})
160
161 endif
162
163 if (nargout > 0)
164 h = cax;
165 endif
166 endfunction
167
168 function deletecolorbar (h, d, hc, pos, opos)
169 ## Don't delete the colorbar and reset the axis size if the
170 ## parent figure is being deleted.
171 if (ishandle (hc) && strcmp (get (hc, "type"), "axes") &&
172 (isempty (gcbf()) || strcmp (get (gcbf(), "beingdeleted"),"off")))
173 if (strcmp (get (hc, "beingdeleted"), "off"))
174 delete (hc);
175 endif
176 if (!isempty (ancestor (h, "axes")) &&
177 strcmp (get (ancestor (h, "axes"), "beingdeleted"), "off"))
178 #set (ancestor (h, "axes"), "position", pos, "outerposition", opos);
179 endif
180 endif
181 endfunction
182
183 function resetaxis (h, d, pos, opos)
184 if (ishandle (h) && strcmp (get (h, "type"), "axes") &&
185 (isempty (gcbf()) || strcmp (get (gcbf(), "beingdeleted"),"off")) &&
186 ishandle (get (h, "axes")))
187 #set (get (h, "axes"), "position", pos, "outerposition", opos);
188 endif
189 endfunction
190
191 function update_colorbar_clim (h, d, hi, vert)
192 if (ishandle (h) && strcmp (get (h, "type"), "image") &&
193 (isempty (gcbf()) || strcmp (get (gcbf(), "beingdeleted"),"off")))
194 clen = rows (get (get (h, "parent"), "colormap"));
195 cext = get (h, "clim");
196 cdiff = (cext(2) - cext(1)) / clen / 2;
197 cmin = cext(1) + cdiff;
198 cmax = cext(2) - cdiff;
199
200 if (vert)
201 set (hi, "ydata", [cmin, cmax]);
202 set (get (hi, "parent"), "ylim", cext);
203 else
204 set (hi, "xdata", [cmin, cmax]);
205 set (get (hi, "parent"), "xlim", cext);
206 endif
207 endif
208 endfunction
209
210 function update_colorbar_axis (h, d, cax)
211 if (ishandle (cax) && strcmp (get (cax, "type"), "axes") &&
212 (isempty (gcbf()) || strcmp (get (gcbf(), "beingdeleted"),"off")))
213 loc = get (cax, "location");
214 obj = get (h);
215 [pos, cpos, vertical, mirror, aspect] = ...
216 __position_colorbox__ (loc, obj, ancestor (h, "figure"));
217
218 if (vertical)
219 if (mirror)
220 set (cax, "xtick", [], "xdir", "normal", "ydir", "normal",
221 "yaxislocation", "right", "position", cpos);
222 else
223 set (cax, "xtick", [], "xdir", "normal", "ydir", "normal",
224 "yaxislocation", "left", "position", cpos);
225 endif
226 else
227 if (mirror)
228 set (cax, "ytick", [], "xdir", "normal", "ydir", "normal",
229 "xaxislocation", "top", "position", cpos);
230 else
231 set (cax, "ytick", [], "xdir", "normal", "ydir", "normal",
232 "xaxislocation", "bottom", "position", cpos);
233 endif
234 endif
235
236 if (! isnan (aspect))
237 aspect
238 set (cax, "dataaspectratio", aspect);
239 endif
240 endif
241 endfunction
242
243 function [pos, cpos, vertical, mirr, aspect] = __position_colorbox__ (cbox, obj, cf)
244
245 pos = obj.position;
246 sz = pos(3:4);
247
248 off = 0;
249 if (strcmpi (obj.dataaspectratiomode, "manual"))
250 r = obj.dataaspectratio;
251 if (pos(3) > pos(4))
252 switch (cbox)
253 case {"east", "eastoutside", "west", "westoutside"}
254 off = [(pos(3) - pos(4)) ./ (r(2) / r(1)), 0];
255 endswitch
256 else
257 switch (cbox)
258 case {"north", "northoutside", "south", "southoutside"}
259 off = [0, (pos(4) - pos(3)) ./ (r(1) / r(2))];
260 ## This shouldn't be here except that gnuplot doesn't have a
261 ## square window and so a square aspect ratio is not square.
262 ## The corrections are empirical.
263 if (strcmp (get (cf, "__backend__"), "gnuplot"))
264 if (length (cbox) > 7 && strcmp (cbox(end-6:end),"outside"))
265 off = off / 2;
266 else
267 off = off / 1.7;
268 endif
269 endif
270 endswitch
271 endif
272 off = off / 2;
273 endif
274
275 switch (cbox)
276 case "northoutside"
277 origin = pos(1:2) + [0., 0.9] .* sz + [1, -1] .* off;
278 sz = sz .* [1.0, 0.06];
279 pos(4) = 0.8 * pos(4);
280 mirr = true;
281 vertical = false;
282 case "north"
283 origin = pos(1:2) + [0.05, 0.9] .* sz + [1, -1] .* off;
284 sz = sz .* [1.0, 0.06] * 0.9;
285 mirr = false;
286 vertical = false;
287 case "southoutside"
288 origin = pos(1:2) + off;
289 sz = sz .* [1.0, 0.06];
290 pos(2) = pos(2) + pos(4) * 0.2;
291 pos(4) = 0.8 * pos(4);
292 mirr = false;
293 vertical = false;
294 case "south"
295 origin = pos(1:2) + [0.05, 0.05] .* sz + off;
296 sz = sz .* [1.0, 0.06] * 0.9;
297 mirr = true;
298 vertical = false;
299 case "eastoutside"
300 origin = pos(1:2) + [0.9, 0] .* sz + [-1, 1] .* off;
301 sz = sz .* [0.06, 1.0];
302 pos(3) = 0.8 * pos(3);
303 mirr = true;
304 vertical = true;
305 case "east"
306 origin = pos(1:2) + [0.9, 0.05] .* sz + [-1, 1] .* off;
307 sz = sz .* [0.06, 1.0] * 0.9;
308 mirr = false;
309 vertical = true;
310 case "westoutside"
311 origin = pos(1:2) + off;
312 sz = sz .* [0.06, 1.0];
313 pos(1) = pos(1) + pos(3) * 0.2;
314 pos(3) = 0.8 * pos(3);
315 mirr = false;
316 vertical = true;
317 case "west"
318 origin = pos(1:2) + [0.05, 0.05] .* sz + off;
319 sz = sz .* [0.06, 1.0] .* 0.9;
320 mirr = true;
321 vertical = true;
322 endswitch
323
324 cpos = [origin, sz];
325
326 if (strcmpi (obj.dataaspectratiomode, "manual"))
327 r = obj.dataaspectratio;
328
329 if (pos(3) > pos(4))
330 if (vertical)
331 aspect = [1, 0.21, 1];
332 else
333 aspect = [0.21, 1, 1];
334 endif
335 else
336 if (vertical)
337 aspect = [1, 0.21, 1];
338 else
339 aspect = [0.21, 1, 1];
340 endif
341 endif
342 else
343 aspect = NaN;
344 endif
345
346 endfunction
94 347
95 %!demo 348 %!demo
96 %! hold off; 349 %! hold off;
97 %! close all; 350 %! close all;
98 %! n = 64; x = kron (1:n,ones(n,1)); x = abs(x - x.'); 351 %! n = 64; x = kron (1:n,ones(n,1)); x = abs(x - x.');