Mercurial > hg > octave-lyh
diff 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 |
line wrap: on
line diff
--- a/scripts/plot/colorbar.m +++ b/scripts/plot/colorbar.m @@ -1,4 +1,4 @@ -## Copyright (C) 2007 David Bateman +## Copyright (C) 2008 David Bateman ## ## This file is part of Octave. ## @@ -47,51 +47,304 @@ ## @end deftypefn -## PKG_ADD: mark_as_command colorbar +function h = colorbar (varargin) + ax = []; + loc = "eastoutside"; + args = {}; + deleting = false; + + i = 1; + while (i <= nargin) + arg = varargin {i++}; -function colorbar (varargin) - - if (nargin > 0 && strcmpi(varargin{1}, "peer")) - if (nargin > 1) - ax = varargin{2}; - if (!isscalar (ax) || ! ishandle (ax) - || strcmp (get (ax, "type"), "axes")) - error ("colorbar: expecting an axes handle following 'peer'"); + if (ischar(arg)) + if (strcmpi (arg, "peer")) + if (i > nargin) + error ("colorbar: missing axes handle after 'peer'"); + else + ax = vargin{i++} + if (!isscalar (ax) || ! ishandle (ax) + || strcmp (get (ax, "type"), "axes")) + error ("colorbar: expecting an axes handle following 'peer'"); + endif + endif + elseif (strcmpi (arg, "north") || strcmpi (arg, "south") + || strcmpi (arg, "east") || strcmpi (arg, "west") + || strcmpi (arg, "northoutside") || strcmpi (arg, "southoutside") + || strcmpi (arg, "eastoutside") || strcmpi (arg, "westoutside")) + loc = arg; + elseif (strcmpi (arg, "off") || strcmpi (arg, "none")) + deleting = true; + else + args{end+1} = arg; endif else - error ("colorbar: misisng axes handle after 'peer'"); + args{end+1} = arg; endif + endwhile + + if (isempty (ax)) + ax = gca (); + endif + obj = get (ax); + + if (deleting) + objs = findobj (get (ax, "parent"), "type", "axes"); + for i = 1 : length (objs) + if (strcmp (get (objs(i), "tag"), "colorbar") && + get (objs(i), "axes") == ax) + delete (objs(i)); + endif + endfor else - ax = gca (); + position = obj.position; + clen = rows (get (get (ax, "parent"), "colormap")); + cext = get (ax, "clim"); + cdiff = (cext(2) - cext(1)) / clen / 2; + cmin = cext(1) + cdiff; + cmax = cext(2) - cdiff; + + orig_pos = obj.position; + orig_opos = obj.outerposition; + [pos, cpos, vertical, mirror, aspect] = ... + __position_colorbox__ (loc, obj, ancestor (ax, "figure")); + set (ax, "activepositionproperty", "position", "position", pos); + + cax = __go_axes__ (get (ax, "parent"), "tag", "colorbar", + "handlevisibility", "off", + "activepositionproperty", "position", + "position", cpos); + addproperty ("location", cax, "radio", + "eastoutside|east|westoutside|west|northoutside|north|southoutside|south", + loc); + addproperty ("axes", cax, "handle", ax); + + if (vertical) + hi = image (cax, [0,1], [cmin, cmax], [1 : clen]'); + if (mirror) + set (cax, "xtick", [], "xdir", "normal", "ydir", "normal", + "ylim", cext, "ylimmode", "manual", + "yaxislocation", "right", args{:}); + else + set (cax, "xtick", [], "xdir", "normal", "ydir", "normal", + "ylim", cext, "ylimmode", "manual", + "yaxislocation", "left", args{:}); + endif + else + hi = image (cax, [cmin, cmax], [0,1], [1 : clen]); + if (mirror) + set (cax, "ytick", [], "xdir", "normal", "ydir", "normal", + "xlim", cext, "xlimmode", "manual", + "xaxislocation", "top", args{:}); + else + set (cax, "ytick", [], "xdir", "normal", "ydir", "normal", + "xlim", cext, "xlimmode", "manual", + "xaxislocation", "bottom", args{:}); + endif + endif + + if (! isnan (aspect)) + set (cax, "dataaspectratio", aspect); + endif + + ctext = text (0, 0, "", "tag", "colorbar","visible", "off", + "handlevisibility", "off", "xliminclude", "off", + "yliminclude", "off", "zliminclude", "off", + "deletefcn", {@deletecolorbar, cax, orig_pos, orig_opos}); + + set (cax, "deletefcn", {@resetaxis, orig_pos, orig_opos}); + + addlistener (ax, "clim", {@update_colorbar_clim, hi, vertical}) + addlistener (ax, "dataaspectratio", {@update_colorbar_axis, cax}) + addlistener (ax, "position", {@update_colorbar_axis, cax}) + endif - pos = "eastoutside"; - for i = 1 : length (varargin) - arg = varargin{i}; - if (length(arg) < 1) - pos = "eastoutside"; - elseif (ischar (arg)) - arg = tolower (arg); - if (strcmp (arg, "off") || strcmp (arg, "none")) - pos = "none"; - elseif (strcmp (arg, "north") || strcmp (arg, "south") - || strcmp (arg, "east") || strcmp (arg, "west") - || strcmp (arg, "northoutside") || strcmp (arg, "southoutside") - || strcmp (arg, "eastoutside") || strcmp (arg, "westoutside")) - pos = arg; + if (nargout > 0) + h = cax; + endif +endfunction + +function deletecolorbar (h, d, hc, pos, opos) + ## Don't delete the colorbar and reset the axis size if the + ## parent figure is being deleted. + if (ishandle (hc) && strcmp (get (hc, "type"), "axes") && + (isempty (gcbf()) || strcmp (get (gcbf(), "beingdeleted"),"off"))) + if (strcmp (get (hc, "beingdeleted"), "off")) + delete (hc); + endif + if (!isempty (ancestor (h, "axes")) && + strcmp (get (ancestor (h, "axes"), "beingdeleted"), "off")) + #set (ancestor (h, "axes"), "position", pos, "outerposition", opos); + endif + endif +endfunction + +function resetaxis (h, d, pos, opos) + if (ishandle (h) && strcmp (get (h, "type"), "axes") && + (isempty (gcbf()) || strcmp (get (gcbf(), "beingdeleted"),"off")) && + ishandle (get (h, "axes"))) + #set (get (h, "axes"), "position", pos, "outerposition", opos); + endif +endfunction + +function update_colorbar_clim (h, d, hi, vert) + if (ishandle (h) && strcmp (get (h, "type"), "image") && + (isempty (gcbf()) || strcmp (get (gcbf(), "beingdeleted"),"off"))) + clen = rows (get (get (h, "parent"), "colormap")); + cext = get (h, "clim"); + cdiff = (cext(2) - cext(1)) / clen / 2; + cmin = cext(1) + cdiff; + cmax = cext(2) - cdiff; + + if (vert) + set (hi, "ydata", [cmin, cmax]); + set (get (hi, "parent"), "ylim", cext); + else + set (hi, "xdata", [cmin, cmax]); + set (get (hi, "parent"), "xlim", cext); + endif + endif +endfunction + +function update_colorbar_axis (h, d, cax) + if (ishandle (cax) && strcmp (get (cax, "type"), "axes") && + (isempty (gcbf()) || strcmp (get (gcbf(), "beingdeleted"),"off"))) + loc = get (cax, "location"); + obj = get (h); + [pos, cpos, vertical, mirror, aspect] = ... + __position_colorbox__ (loc, obj, ancestor (h, "figure")); + + if (vertical) + if (mirror) + set (cax, "xtick", [], "xdir", "normal", "ydir", "normal", + "yaxislocation", "right", "position", cpos); else - error ("colorbar: unrecognized position argument"); + set (cax, "xtick", [], "xdir", "normal", "ydir", "normal", + "yaxislocation", "left", "position", cpos); endif else - error ("colorbar: expecting string arguments"); + if (mirror) + set (cax, "ytick", [], "xdir", "normal", "ydir", "normal", + "xaxislocation", "top", "position", cpos); + else + set (cax, "ytick", [], "xdir", "normal", "ydir", "normal", + "xaxislocation", "bottom", "position", cpos); + endif + endif + + if (! isnan (aspect)) + aspect + set (cax, "dataaspectratio", aspect); + endif + endif +endfunction + +function [pos, cpos, vertical, mirr, aspect] = __position_colorbox__ (cbox, obj, cf) + + pos = obj.position; + sz = pos(3:4); + + off = 0; + if (strcmpi (obj.dataaspectratiomode, "manual")) + r = obj.dataaspectratio; + if (pos(3) > pos(4)) + switch (cbox) + case {"east", "eastoutside", "west", "westoutside"} + off = [(pos(3) - pos(4)) ./ (r(2) / r(1)), 0]; + endswitch + else + switch (cbox) + case {"north", "northoutside", "south", "southoutside"} + off = [0, (pos(4) - pos(3)) ./ (r(1) / r(2))]; + ## This shouldn't be here except that gnuplot doesn't have a + ## square window and so a square aspect ratio is not square. + ## The corrections are empirical. + if (strcmp (get (cf, "__backend__"), "gnuplot")) + if (length (cbox) > 7 && strcmp (cbox(end-6:end),"outside")) + off = off / 2; + else + off = off / 1.7; + endif + endif + endswitch endif - endfor + off = off / 2; + endif - set (ax, "__colorbar__", pos); + switch (cbox) + case "northoutside" + origin = pos(1:2) + [0., 0.9] .* sz + [1, -1] .* off; + sz = sz .* [1.0, 0.06]; + pos(4) = 0.8 * pos(4); + mirr = true; + vertical = false; + case "north" + origin = pos(1:2) + [0.05, 0.9] .* sz + [1, -1] .* off; + sz = sz .* [1.0, 0.06] * 0.9; + mirr = false; + vertical = false; + case "southoutside" + origin = pos(1:2) + off; + sz = sz .* [1.0, 0.06]; + pos(2) = pos(2) + pos(4) * 0.2; + pos(4) = 0.8 * pos(4); + mirr = false; + vertical = false; + case "south" + origin = pos(1:2) + [0.05, 0.05] .* sz + off; + sz = sz .* [1.0, 0.06] * 0.9; + mirr = true; + vertical = false; + case "eastoutside" + origin = pos(1:2) + [0.9, 0] .* sz + [-1, 1] .* off; + sz = sz .* [0.06, 1.0]; + pos(3) = 0.8 * pos(3); + mirr = true; + vertical = true; + case "east" + origin = pos(1:2) + [0.9, 0.05] .* sz + [-1, 1] .* off; + sz = sz .* [0.06, 1.0] * 0.9; + mirr = false; + vertical = true; + case "westoutside" + origin = pos(1:2) + off; + sz = sz .* [0.06, 1.0]; + pos(1) = pos(1) + pos(3) * 0.2; + pos(3) = 0.8 * pos(3); + mirr = false; + vertical = true; + case "west" + origin = pos(1:2) + [0.05, 0.05] .* sz + off; + sz = sz .* [0.06, 1.0] .* 0.9; + mirr = true; + vertical = true; + endswitch + + cpos = [origin, sz]; + + if (strcmpi (obj.dataaspectratiomode, "manual")) + r = obj.dataaspectratio; + + if (pos(3) > pos(4)) + if (vertical) + aspect = [1, 0.21, 1]; + else + aspect = [0.21, 1, 1]; + endif + else + if (vertical) + aspect = [1, 0.21, 1]; + else + aspect = [0.21, 1, 1]; + endif + endif + else + aspect = NaN; + endif endfunction - %!demo %! hold off; %! close all;