]> Creatis software - CreaPhase.git/blobdiff - octave_packages/m/plot/plotyy.m
update packages
[CreaPhase.git] / octave_packages / m / plot / plotyy.m
diff --git a/octave_packages/m/plot/plotyy.m b/octave_packages/m/plot/plotyy.m
new file mode 100644 (file)
index 0000000..8de6586
--- /dev/null
@@ -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
+## <http://www.gnu.org/licenses/>.
+
+## -*- 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
+