changeset 29149:e3e887d5f631

plotyy.m: Fix error when called repeatedly (bug #53461). * scripts/plot/draw/plotyy.m: Allow first argument to be a 2-vector with both plotyy axes handles from a previous call. (__plotyy__): Reset secondary axes so that it doesn't accumulate more and more listeners. (deleteplotyy): Do not delete sister axes if called through "plotyy" (most likely via "reset"). * newplot.m: Do not delete plotyy axes when called through "plotyy".
author Markus Mützel <markus.muetzel@gmx.de>
date Sun, 06 Dec 2020 14:56:29 +0100
parents d9ac99164c18
children 27dc4dae6826
files scripts/plot/draw/plotyy.m scripts/plot/util/newplot.m
diffstat 2 files changed, 29 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/plot/draw/plotyy.m	Sun Dec 06 14:56:04 2020 +0100
+++ b/scripts/plot/draw/plotyy.m	Sun Dec 06 14:56:29 2020 +0100
@@ -43,8 +43,10 @@
 ## The function to use for each of the plots can be independently defined
 ## with @var{fun1} and @var{fun2}.
 ##
-## If the first argument @var{hax} is an axes handle, then it defines
-## the principal axes in which to plot the @var{x1} and @var{y1} data.
+## The first argument @var{hax} can be an axes handle to the principal axes in
+## which to plot the @var{x1} and @var{y1} data.  It can also be a two-element
+## vector with the axes handles to the primary and secondary axes (see output
+## @var{ax}).
 ##
 ## The return value @var{ax} is a vector with the axes handles of the two
 ## y-axes.  @var{h1} and @var{h2} are handles to the objects generated by the
@@ -72,7 +74,17 @@
 
 function [ax, h1, h2] = plotyy (varargin)
 
-  [hax, varargin] = __plt_get_axis_arg__ ("plotyy", varargin{:});
+  ## Check if first argument is axes handle(s).
+  hax = [];
+  if numel (varargin) > 0
+    if (isscalar (varargin{1}))
+      [hax, varargin] = __plt_get_axis_arg__ ("plotyy", varargin{:});
+    elseif (numel (varargin{1}) == 2 && all (isaxes (varargin{1})))
+      ## First argument might be vector with the two handles to plotyy axes.
+      hax = varargin{1}(1);
+      varargin(1) = [];
+    endif
+  endif
 
   nargin = numel (varargin);
   if (nargin < 4 || nargin > 6)
@@ -136,6 +148,12 @@
 
   axes (ax(2));
 
+  if (strcmp (get (ax(1), "nextplot"), "replace"))
+    ## Reset axes here because we don't want it to reset later after we set
+    ## some properties in preparation for the plot in the secondary axes.
+    reset (ax(2));
+  endif
+
   colors = get (ax(1), "colororder");
   set (ax(2), "colororder", circshift (colors, -numel (h1), 1));
 
@@ -198,21 +216,20 @@
   ## Store the axes handles for the sister axes.
   if (! isprop (ax(1), "__plotyy_axes__"))
     addproperty ("__plotyy_axes__", ax(1), "data");
-    set (ax(1), "__plotyy_axes__", ax);
-  else
-    set (ax(1), "__plotyy_axes__", ax);
   endif
+  set (ax(1), "__plotyy_axes__", ax);
   if (! isprop (ax(2), "__plotyy_axes__"))
     addproperty ("__plotyy_axes__", ax(2), "data");
-    set (ax(2), "__plotyy_axes__", ax);
-  else
-    set (ax(2), "__plotyy_axes__", ax);
   endif
+  set (ax(2), "__plotyy_axes__", ax);
+
+  ## Call position property listener explicitly
+  update_prop (ax(1), [], ax(2), "position");
 
 endfunction
 
 function deleteplotyy (h, ~, ax2, t2)
-  if (isaxes (ax2))
+  if (isaxes (ax2) && ! any (strcmp({dbstack().name}, "plotyy")))
     set (t2, "deletefcn", []);
     delete (ax2);
   endif
--- a/scripts/plot/util/newplot.m	Sun Dec 06 14:56:04 2020 +0100
+++ b/scripts/plot/util/newplot.m	Sun Dec 06 14:56:29 2020 +0100
@@ -195,7 +195,8 @@
         kids(kids == hkid) = [];
         delete (kids);
       else
-        if (isprop (ca, "__plotyy_axes__"))
+        if (isprop (ca, "__plotyy_axes__") ...
+            && ! any (strcmp({dbstack().name}, "plotyy")))
           ## Hack for bug #44246.  There is no way to reset or remove a
           ## property created with addproperty short of deleting the object.
           delete (ca);