1 ## Copyright (C) 2008-2012 David Bateman
3 ## This file is part of Octave.
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
7 ## the Free Software Foundation; either version 3 of the License, or (at
8 ## your option) any later version.
10 ## Octave is distributed in the hope that it will be useful, but
11 ## WITHOUT ANY WARRANTY; without even the implied warranty of
12 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 ## General Public License for more details.
15 ## You should have received a copy of the GNU General Public License
16 ## along with Octave; see the file COPYING. If not, see
17 ## <http://www.gnu.org/licenses/>.
20 ## @deftypefn {Function File} {} colorbar (@var{s})
21 ## @deftypefnx {Function File} {} colorbar ("peer", @var{h}, @dots{})
22 ## Add a colorbar to the current axes. Valid values for @var{s} are
25 ## @item "EastOutside"
26 ## Place the colorbar outside the plot to the right. This is the default.
29 ## Place the colorbar inside the plot to the right.
31 ## @item "WestOutside"
32 ## Place the colorbar outside the plot to the left.
35 ## Place the colorbar inside the plot to the left.
37 ## @item "NorthOutside"
38 ## Place the colorbar above the plot.
41 ## Place the colorbar at the top of the plot.
43 ## @item "SouthOutside"
44 ## Place the colorbar under the plot.
47 ## Place the colorbar at the bottom of the plot.
49 ## @item "Off", "None"
50 ## Remove any existing colorbar from the plot.
53 ## If the argument "peer" is given, then the following argument is treated
54 ## as the axes handle on which to add the colorbar.
57 function h = colorbar (varargin)
67 if (strcmpi (arg, "peer"))
69 error ("colorbar: missing axes handle after \"peer\"");
72 if (!isscalar (ax) || ! ishandle (ax)
73 || ! strcmp (get (ax, "type"), "axes"))
74 error ("colorbar: expecting an axes handle following \"peer\"");
77 elseif (strcmpi (arg, "north") || strcmpi (arg, "south")
78 || strcmpi (arg, "east") || strcmpi (arg, "west")
79 || strcmpi (arg, "northoutside") || strcmpi (arg, "southoutside")
80 || strcmpi (arg, "eastoutside") || strcmpi (arg, "westoutside"))
82 elseif (strcmpi (arg, "location") && i <= nargin)
83 loc = tolower (varargin{i++});
84 elseif (strcmpi (arg, "off") || strcmpi (arg, "none"))
98 showhiddenhandles = get (0, "showhiddenhandles");
100 set (0, "showhiddenhandles", "on");
101 cax = findobj (get (ax, "parent"), "tag", "colorbar", "type", "axes", "axes", ax);
105 unwind_protect_cleanup
106 set (0, "showhiddenhandles", showhiddenhandles);
110 ## FIXME - Matlab does not require the "position" property to be active.
111 ## Is there a way to determine the plotbox position for the
112 ## gnuplot graphics toolkit with the outerposition is active?
113 set (ax, "activepositionproperty", "position");
115 obj.__my_handle__ = ax;
116 position = obj.position;
117 clen = rows (get (get (ax, "parent"), "colormap"));
118 cext = get (ax, "clim");
119 cdiff = (cext(2) - cext(1)) / clen / 2;
120 cmin = cext(1) + cdiff;
121 cmax = cext(2) - cdiff;
123 [pos, cpos, vertical, mirror] = ...
124 __position_colorbox__ (loc, obj, ancestor (ax, "figure"));
125 set (ax, "position", pos);
127 cax = __go_axes__ (get (ax, "parent"), "tag", "colorbar",
128 "handlevisibility", "on",
129 "activepositionproperty", "position",
131 addproperty ("location", cax, "radio",
132 "eastoutside|east|westoutside|west|northoutside|north|southoutside|south",
134 addproperty ("axes", cax, "handle", ax);
137 hi = image (cax, [0,1], [cmin, cmax], [1 : clen]');
139 set (cax, "xtick", [], "xdir", "normal", "ydir", "normal",
140 "ylim", cext, "ylimmode", "manual",
141 "yaxislocation", "right", args{:});
143 set (cax, "xtick", [], "xdir", "normal", "ydir", "normal",
144 "ylim", cext, "ylimmode", "manual",
145 "yaxislocation", "left", args{:});
148 hi = image (cax, [cmin, cmax], [0,1], [1 : clen]);
150 set (cax, "ytick", [], "xdir", "normal", "ydir", "normal",
151 "xlim", cext, "xlimmode", "manual",
152 "xaxislocation", "top", args{:});
154 set (cax, "ytick", [], "xdir", "normal", "ydir", "normal",
155 "xlim", cext, "xlimmode", "manual",
156 "xaxislocation", "bottom", args{:});
160 ctext = text (0, 0, "", "tag", "colorbar","visible", "off",
161 "handlevisibility", "off", "xliminclude", "off",
162 "yliminclude", "off", "zliminclude", "off",
163 "deletefcn", {@deletecolorbar, cax, obj});
165 set (cax, "deletefcn", {@resetaxis, obj});
167 addlistener (ax, "clim", {@update_colorbar_clim, hi, vertical});
168 addlistener (ax, "plotboxaspectratio", {@update_colorbar_axis, cax, obj});
169 addlistener (ax, "plotboxaspectratiomode", {@update_colorbar_axis, cax, obj});
170 addlistener (ax, "dataaspectratio", {@update_colorbar_axis, cax, obj});
171 addlistener (ax, "dataaspectratiomode", {@update_colorbar_axis, cax, obj});
172 addlistener (ax, "position", {@update_colorbar_axis, cax, obj});
181 function deletecolorbar (h, d, hc, orig_props)
182 ## Don't delete the colorbar and reset the axis size if the
183 ## parent figure is being deleted.
184 if (ishandle (hc) && strcmp (get (hc, "type"), "axes")
185 && (isempty (gcbf()) || strcmp (get (gcbf(), "beingdeleted"),"off")))
186 if (strcmp (get (hc, "beingdeleted"), "off"))
189 if (!isempty (ancestor (h, "axes"))
190 && strcmp (get (ancestor (h, "axes"), "beingdeleted"), "off"))
191 set (ancestor (h, "axes"), "position", orig_props.position, ...
192 "outerposition", orig_props.outerposition, ...
193 "activepositionproperty", orig_props.activepositionproperty);
198 function resetaxis (h, d, orig_props)
199 if (ishandle (h) && strcmp (get (h, "type"), "axes")
200 && (isempty (gcbf()) || strcmp (get (gcbf(), "beingdeleted"),"off"))
201 && ishandle (get (h, "axes")))
202 set (get (h, "axes"), "position", orig_props.position, ...
203 "outerposition", orig_props.outerposition, ...
204 "activepositionproperty", orig_props.activepositionproperty);
208 function update_colorbar_clim (h, d, hi, vert)
209 if (ishandle (h) && strcmp (get (h, "type"), "image")
210 && (isempty (gcbf()) || strcmp (get (gcbf(), "beingdeleted"),"off")))
211 clen = rows (get (get (h, "parent"), "colormap"));
212 cext = get (h, "clim");
213 cdiff = (cext(2) - cext(1)) / clen / 2;
214 cmin = cext(1) + cdiff;
215 cmax = cext(2) - cdiff;
218 set (hi, "ydata", [cmin, cmax]);
219 set (get (hi, "parent"), "ylim", cext);
221 set (hi, "xdata", [cmin, cmax]);
222 set (get (hi, "parent"), "xlim", cext);
227 function update_colorbar_axis (h, d, cax, orig_props)
229 if (ishandle (cax) && strcmp (get (cax, "type"), "axes")
230 && (isempty (gcbf()) || strcmp (get (gcbf(), "beingdeleted"),"off")))
231 loc = get (cax, "location");
233 obj.__my_handle__ = h;
234 obj.position = orig_props.position;
235 obj.outerposition = orig_props.outerposition;
236 [pos, cpos, vertical, mirror] = ...
237 __position_colorbox__ (loc, obj, ancestor (h, "figure"));
241 set (cax, "xtick", [], "xdir", "normal", "ydir", "normal",
242 "yaxislocation", "right", "position", cpos);
244 set (cax, "xtick", [], "xdir", "normal", "ydir", "normal",
245 "yaxislocation", "left", "position", cpos);
249 set (cax, "ytick", [], "xdir", "normal", "ydir", "normal",
250 "xaxislocation", "top", "position", cpos);
252 set (cax, "ytick", [], "xdir", "normal", "ydir", "normal",
253 "xaxislocation", "bottom", "position", cpos);
260 function [pos, cpos, vertical, mirr] = __position_colorbox__ (cbox, obj, cf)
262 ## This will always represent the position prior to adding the colorbar.
266 if (strcmpi (obj.plotboxaspectratiomode, "manual")
267 || strcmpi (obj.dataaspectratiomode, "manual"))
268 if (isempty (strfind (cbox, "outside")))
273 if (isempty (strfind (cbox, "east")) && isempty (strfind (cbox, "west")))
278 if (strcmp (get (cf, "__graphics_toolkit__"), "gnuplot")
279 && strcmp (obj.activepositionproperty, "outerposition"))
280 obj.outerposition = obj.outerposition .* [1, 1, scale];
281 off = 0.5 * (obj.outerposition (3:4) - __actual_axis_position__ (obj)(3:4));
283 obj.position = obj.position .* [1, 1, scale];
284 off = 0.5 * (obj.position (3:4) - __actual_axis_position__ (obj)(3:4));
292 origin = pos(1:2) + [0., 0.9] .* sz + [1, -1] .* off;
293 sz = sz .* [1.0, 0.06];
294 pos(4) = 0.8 * pos(4);
298 origin = pos(1:2) + [0.05, 0.9] .* sz + [1, -1] .* off;
299 sz = sz .* [1.0, 0.06] * 0.9;
303 origin = pos(1:2) + off;
304 sz = sz .* [1.0, 0.06];
305 pos(2) = pos(2) + pos(4) * 0.2;
306 pos(4) = 0.8 * pos(4);
310 origin = pos(1:2) + [0.05, 0.05] .* sz + off;
311 sz = sz .* [1.0, 0.06] * 0.9;
315 origin = pos(1:2) + [0.9, 0] .* sz + [-1, 1] .* off;
316 sz = sz .* [0.06, 1.0];
317 pos(3) = 0.8 * pos(3);
321 origin = pos(1:2) + [0.9, 0.05] .* sz + [-1, 1] .* off;
322 sz = sz .* [0.06, 1.0] * 0.9;
326 origin = pos(1:2) + off;
327 sz = sz .* [0.06, 1.0];
328 pos(1) = pos(1) + pos(3) * 0.2;
329 pos(3) = 0.8 * pos(3);
333 origin = pos(1:2) + [0.05, 0.05] .* sz + off;
334 sz = sz .* [0.06, 1.0] .* 0.9;
341 if (strcmpi (obj.plotboxaspectratiomode, "manual")
342 || strcmpi (obj.dataaspectratiomode, "manual"))
344 actual_pos = __actual_axis_position__ (obj);
345 if (strfind (cbox, "outside"))
351 ## Ensure north or south colorbars are the proper length
352 dx = (1-scale)*actual_pos(3);
353 cpos(1) = actual_pos(1) + dx/2;
354 cpos(3) = actual_pos(3) - dx;
356 ## Ensure east or west colorbars are the proper height
357 dy = (1-scale)*actual_pos(4);
358 cpos(2) = actual_pos(2) + dy/2;
359 cpos(4) = actual_pos(4) - dy;
367 %! n = 64; x = kron (1:n,ones(n,1)); x = abs(x - x.');
373 %! n = 64; x = kron (1:n,ones(n,1)); x = abs(x - x.');
375 %! colorbar("westoutside");
379 %! n = 64; x = kron (1:n,ones(n,1)); x = abs(x - x.');
381 %! colorbar("peer", gca (), "northoutside");
385 %! n = 64; x = kron (1:n,ones(n,1)); x = abs(x - x.');
387 %! colorbar("southoutside");
404 %! colorbar("north");
407 %! colorbar("south");
411 %! n = 64; x = kron (1:n,ones(n,1)); x = abs(x - x.');
417 %! colorbar("westoutside");
420 %! colorbar("northoutside");
423 %! colorbar("southoutside");
427 %! n = 64; x = kron (1:n,ones(n,1)); x = abs(x - x.');
435 %! colorbar("westoutside");
439 %! n = 64; x = kron (1:n,ones(n,1)); x = abs(x - x.');
443 %! colorbar("northoutside");
447 %! colorbar("southoutside");
451 %! n = 64; x = kron (1:n,ones(n,1)); x = abs(x - x.');
459 %! colorbar("westoutside");
463 %! n = 64; x = kron (1:n,ones(n,1)); x = abs(x - x.');
467 %! colorbar("northoutside");
471 %! colorbar("southoutside");
475 %! n = 64; x = kron (1:n,ones(n,1)); x = abs(x - x.');
481 %! colorbar("westoutside");
485 %! n = 64; x = kron (1:n,ones(n,1)); x = abs(x - x.');
488 %! colorbar("northoutside");
491 %! colorbar("southoutside");
495 %! n = 64; x = kron (1:n,ones(n,1)); x = abs(x - x.');
501 %! colorbar("westoutside");
505 %! n = 64; x = kron (1:n,ones(n,1)); x = abs(x - x.');
508 %! colorbar("northoutside");
511 %! colorbar("southoutside");
515 %! n = 64; x = kron (1:n,ones(n,1)); x = abs(x - x.');
530 %! n = 64; x = kron (1:n,ones(n,1)); x = abs(x - x.');
539 %! n = 64; x = kron (1:n,ones(n,1)); x = abs(x - x.');
548 %! imagesc (1./hilb(99));
550 %! set (h, 'yscale', 'log');
554 %! imagesc (log10 (1 ./ hilb (99)));
556 %! ytick = get(h, "ytick");
557 %! set (h, "yticklabel", sprintf ('10^{%g}|', ytick));
561 %! n=5;x=linspace(0,5,n);y=linspace(0,1,n);
562 %! imagesc(1./hilb(n)); axis equal; colorbar
566 %! n=5;x=linspace(0,5,n);y=linspace(0,1,n);
567 %! imagesc(x,y,1./hilb(n)); axis equal; colorbar
571 %! n=5;x=linspace(0,5,n);y=linspace(0,1,n);
572 %! imagesc(y,x,1./hilb(n)); axis equal; colorbar
573 ## This requires that the axes position be properly determined for "axes equal"
592 %! colorbar ("eastoutside")
597 %! pcolor (peaks (20))
598 %! shading ("interp")
599 %! axis ("tight", "square")
601 #%! axes('color','none','box','on','activepositionproperty','position')
612 %! colorbar ("eastoutside")