X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?p=CreaPhase.git;a=blobdiff_plain;f=octave_packages%2Fm%2Fplot%2Fplotyy.m;fp=octave_packages%2Fm%2Fplot%2Fplotyy.m;h=8de6586247b351b703ea811186e0beb032dfb0df;hp=0000000000000000000000000000000000000000;hb=1c0469ada9531828709108a4882a751d2816994a;hpb=63de9f36673d49121015e3695f2c336ea92bc278 diff --git a/octave_packages/m/plot/plotyy.m b/octave_packages/m/plot/plotyy.m new file mode 100644 index 0000000..8de6586 --- /dev/null +++ b/octave_packages/m/plot/plotyy.m @@ -0,0 +1,327 @@ +## Copyright (C) 2007-2012 David Bateman +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or (at +## your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## . + +## -*- texinfo -*- +## @deftypefn {Function File} {} plotyy (@var{x1}, @var{y1}, @var{x2}, @var{y2}) +## @deftypefnx {Function File} {} plotyy (@dots{}, @var{fun}) +## @deftypefnx {Function File} {} plotyy (@dots{}, @var{fun1}, @var{fun2}) +## @deftypefnx {Function File} {} plotyy (@var{h}, @dots{}) +## @deftypefnx {Function File} {[@var{ax}, @var{h1}, @var{h2}] =} plotyy (@dots{}) +## Plot two sets of data with independent y-axes. The arguments @var{x1} and +## @var{y1} define the arguments for the first plot and @var{x1} and @var{y2} +## for the second. +## +## By default the arguments are evaluated with +## @code{feval (@@plot, @var{x}, @var{y})}. However the type of plot can be +## modified with the @var{fun} argument, in which case the plots are +## generated by @code{feval (@var{fun}, @var{x}, @var{y})}. @var{fun} can be +## a function handle, an inline function or a string of a function name. +## +## The function to use for each of the plots can be independently defined +## with @var{fun1} and @var{fun2}. +## +## If given, @var{h} defines the principal axis in which to plot the @var{x1} +## and @var{y1} data. The return value @var{ax} is a two element vector with +## the axis handles of the two plots. @var{h1} and @var{h2} are handles to +## the objects generated by the plot commands. +## +## @example +## @group +## x = 0:0.1:2*pi; +## y1 = sin (x); +## y2 = exp (x - 1); +## ax = plotyy (x, y1, x - 1, y2, @@plot, @@semilogy); +## xlabel ("X"); +## ylabel (ax(1), "Axis 1"); +## ylabel (ax(2), "Axis 2"); +## @end group +## @end example +## @end deftypefn + +function [Ax, H1, H2] = plotyy (varargin) + + ## Don't use __plt_get_axis_arg__ here as ax is a two vector for plotyy + if (nargin > 1 && length (varargin{1}) == 2 && ishandle(varargin{1}(1)) + && ishandle(varargin{1}(2)) + && all (floor (varargin{1}) != varargin{1})) + obj1 = get (varargin{1}(1)); + obj2 = get (varargin{1}(2)); + if (strcmp (obj1.type, "axes") || strcmp (obj2.type, "axes")) + ax = [obj1, obj2]; + varargin(1) = []; + if (isempty (varargin)) + varargin = {}; + endif + else + error ("plotyy: expecting first argument to be axes handle"); + endif + oldh = gca (); + else + f = get (0, "currentfigure"); + if (isempty (f)) + f = figure (); + endif + ca = get (f, "currentaxes"); + if (isempty (ca)) + ax = []; + elseif (ishandle (ca) && isprop (ca, "__plotyy_axes__")) + ax = get (ca, "__plotyy_axes__"); + else + ax = ca; + endif + if (length (ax) > 2) + for i = 3 : length (ax) + delete (ax (i)); + endfor + ax = ax(1:2); + elseif (length (ax) == 1) + ax(2) = axes (); + elseif (isempty (ax)) + ax(1) = axes (); + ax(2) = axes (); + ca = ax(2); + endif + if (nargin < 2) + varargin = {}; + endif + oldh = ca; + endif + + if (nargin < 4) + print_usage (); + endif + + unwind_protect + [ax, h1, h2] = __plotyy__ (ax, varargin{:}); + unwind_protect_cleanup + ## Only change back to the old axis if we didn't delete it + if (ishandle(oldh) && strcmp (get (oldh, "type"), "axes")) + axes (oldh); + endif + end_unwind_protect + + if (nargout > 0) + Ax = ax; + H1 = h1; + H2 = h2; + endif + +endfunction + +function [ax, h1, h2] = __plotyy__ (ax, x1, y1, x2, y2, varargin) + if (nargin > 5) + fun1 = varargin{1}; + else + fun1 = @plot; + endif + if (nargin > 6) + fun2 = varargin{2}; + else + fun2 = fun1; + endif + + xlim = [min([x1(:); x2(:)]), max([x1(:); x2(:)])]; + + if (ishandle(ax(1)) && strcmp (get (ax(1), "type"), "axes")) + axes (ax(1)); + else + ax(1) = axes (); + endif + newplot (); + h1 = feval (fun1, x1, y1); + + set (ax(1), "ycolor", getcolor (h1(1))); + set (ax(1), "xlim", xlim); + set (ax(1), "color", "none"); + + cf = gcf (); + set (cf, "nextplot", "add"); + + if (ishandle(ax(2)) && strcmp (get (ax(2), "type"), "axes")) + axes (ax(2)); + else + ax(2) = axes (); + endif + newplot (); + + colors = get (ax(1), "colororder"); + set (ax(2), "colororder", [colors(2:end,:); colors(1,:)]); + + if (strcmp (get (ax(1), "autopos_tag"), "subplot")) + set (ax(2), "autopos_tag", "subplot"); + else + set (ax, "activepositionproperty", "position"); + endif + + h2 = feval (fun2, x2, y2); + set (ax(2), "yaxislocation", "right"); + set (ax(2), "ycolor", getcolor (h2(1))); + + + if (strcmp (get(ax(1), "activepositionproperty"), "position")) + set (ax(2), "position", get (ax(1), "position")); + else + set (ax(2), "outerposition", get (ax(1), "outerposition")); + set (ax(2), "looseinset", get (ax(1), "looseinset")); + endif + + set (ax(2), "xlim", xlim); + set (ax(2), "color", "none"); + set (ax(2), "box", "off"); + + ## Add invisible text objects that when destroyed, + ## also remove the other axis + t1 = text (0, 0, "", "parent", ax(1), "tag", "plotyy", + "handlevisibility", "off", "visible", "off", + "xliminclude", "off", "yliminclude", "off"); + t2 = text (0, 0, "", "parent", ax(2), "tag", "plotyy", + "handlevisibility", "off", "visible", "off", + "xliminclude", "off", "yliminclude", "off"); + + set (t1, "deletefcn", {@deleteplotyy, ax(2), t2}); + set (t2, "deletefcn", {@deleteplotyy, ax(1), t1}); + + addlistener (ax(1), "position", {@update_position, ax(2)}); + addlistener (ax(2), "position", {@update_position, ax(1)}); + addlistener (ax(1), "outerposition", {@update_position, ax(2)}); + addlistener (ax(2), "outerposition", {@update_position, ax(1)}); + addlistener (ax(1), "looseinset", {@update_position, ax(2)}); + addlistener (ax(2), "looseinset", {@update_position, ax(1)}); + addlistener (ax(1), "view", {@update_position, ax(2)}); + addlistener (ax(2), "view", {@update_position, ax(1)}); + addlistener (ax(1), "plotboxaspectratio", {@update_position, ax(2)}); + addlistener (ax(2), "plotboxaspectratio", {@update_position, ax(1)}); + addlistener (ax(1), "plotboxaspectratiomode", {@update_position, ax(2)}); + addlistener (ax(2), "plotboxaspectratiomode", {@update_position, ax(1)}); + + ## Store the axes handles for the sister axes. + if (ishandle (ax(1)) && ! isprop (ax(1), "__plotyy_axes__")) + addproperty ("__plotyy_axes__", ax(1), "data", ax); + elseif (ishandle (ax(1))) + set (ax(1), "__plotyy_axes__", ax); + else + error ("plotyy.m: This shouldn't happen. File a bug report.") + endif + if (ishandle (ax(2)) && ! isprop (ax(2), "__plotyy_axes__")) + addproperty ("__plotyy_axes__", ax(2), "data", ax); + elseif (ishandle (ax(2))) + set (ax(2), "__plotyy_axes__", ax); + else + error ("plotyy.m: This shouldn't happen. File a bug report.") + endif +endfunction + +%!demo +%! clf +%! x = 0:0.1:2*pi; +%! y1 = sin (x); +%! y2 = exp (x - 1); +%! ax = plotyy (x, y1, x - 1, y2, @plot, @semilogy); +%! xlabel ("X"); +%! ylabel (ax(1), "Axis 1"); +%! ylabel (ax(2), "Axis 2"); +%! axes (ax(1)) +%! text (0.5, 0.5, "Left Axis", ... +%! "color", [0 0 1], "horizontalalignment", "center") +%! axes (ax(2)) +%! text (4.5, 80, "Right Axis", ... +%! "color", [0 0.5 0], "horizontalalignment", "center") + +%!demo +%! clf +%! x = linspace (-1, 1, 201); +%! subplot (2, 2, 1) +%! plotyy (x, sin(pi*x), x, 10*cos(pi*x)) +%! subplot (2, 2, 2) +%! surf (peaks (25)) +%! subplot (2, 2, 3) +%! contour (peaks (25)) +%! subplot (2, 2, 4) +%! plotyy (x, 10*sin(2*pi*x), x, cos(2*pi*x)) +%! axis square + +%!demo +%! clf +%! x = linspace (-1, 1, 201); +%! subplot (1, 1, 1); +%! hax = plotyy (x, sin(pi*x), x, cos(pi*x)); +%! ylabel ("Blue and on the Left") +%! ylabel (hax(2), "Green and on the Right") +%! xlabel ("xlabel") + +function deleteplotyy (h, d, ax2, t2) + if (ishandle (ax2) && strcmp (get (ax2, "type"), "axes") + && (isempty (gcbf()) || strcmp (get (gcbf(), "beingdeleted"),"off")) + && strcmp (get (ax2, "beingdeleted"), "off")) + set (t2, "deletefcn", []); + delete (ax2); + endif +endfunction + +function update_position (h, d, ax2) + persistent recursion = false; + + ## Don't allow recursion + if (! recursion) + unwind_protect + recursion = true; + view = get (h, "view"); + oldview = get (ax2, "view"); + plotboxaspectratio = get (h, "plotboxaspectratio"); + oldplotboxaspectratio = get (ax2, "plotboxaspectratio"); + plotboxaspectratiomode = get (h, "plotboxaspectratiomode"); + oldplotboxaspectratiomode = get (ax2, "plotboxaspectratiomode"); + + if (strcmp (get(h, "activepositionproperty"), "position")) + position = get (h, "position"); + oldposition = get (ax2, "position"); + if (! (isequal (position, oldposition) && isequal (view, oldview))) + set (ax2, "position", position, "view", view); + endif + else + outerposition = get (h, "outerposition"); + oldouterposition = get (ax2, "outerposition"); + if (! (isequal (outerposition, oldouterposition) && isequal (view, oldview))) + set (ax2, "outerposition", outerposition, "view", view); + endif + endif + + if (! (isequal (plotboxaspectratio, oldplotboxaspectratio) + && isequal (plotboxaspectratiomode, oldplotboxaspectratiomode))) + set (ax2, "plotboxaspectratio", plotboxaspectratio); + set (ax2, "plotboxaspectratiomode", plotboxaspectratiomode); + endif + unwind_protect_cleanup + recursion = false; + end_unwind_protect + endif +endfunction + +function color = getcolor (ax) + obj = get (ax); + if (isfield (obj, "color")) + color = obj.color; + elseif (isfield (obj, "facecolor") && ! ischar (obj.facecolor)) + color = obj.facecolor; + elseif (isfield (obj, "edgecolor") && ! ischar (obj.edgecolor)) + color = obj.edgecolor; + else + color = [0, 0, 0]; + endif +endfunction +