changeset 26664:a7dfb00d5bf5

axis.m: Fix issues with "equal" argument (bug #55619, bug #55614, bug #55574, bug #55514, bug #54848, bug #53724, bug #53504, bug #53336, bug #51938, bug #50356). * axis.m (__axis__): Determine whether axes is 2-D or 3-D. For 2-D axes, determine the aspect ratio from the "position" property of the axes measured in pixels because "plotboxaspectratio" is not valid. After setting "dataaspectratio" property to [1 1 1] for equal length axes, restore the "plotboxaspectratio" for 2-D axes, or set it to [1 1 1] for 3-D axes. This mimics what Matlab does.
author Rik <rik@octave.org>
date Fri, 01 Feb 2019 22:16:15 -0800
parents fad3f19de1be
children f9dbc287f908
files scripts/plot/appearance/axis.m
diffstat 1 files changed, 28 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/plot/appearance/axis.m	Fri Feb 01 20:44:15 2019 +0000
+++ b/scripts/plot/appearance/axis.m	Fri Feb 01 22:16:15 2019 -0800
@@ -205,32 +205,41 @@
         set (ca, "dataaspectratiomode", "auto",
                  "plotboxaspectratio", [1, 1, 1]);
       elseif (strcmp (opt, "equal"))
-        ## Get position of axis in pixels
-        ca_units = get (ca, "units");
-        set (ca, "units", "pixels");
-        axis_pos = get (ca, "position");
-        set (ca, "units", ca_units);
+        is2dview = (get (ca, "view")(2) == 90);
+        if (is2dview)
+          ## Save & later restore axes aspect ratio
+          ca_units = get (ca, "units");
+          set (ca, "units", "pixels");
+          axis_pos = get (ca, "position");
+          set (ca, "units", ca_units);
+          pbratio = [axis_pos(3), axis_pos(4), axis_pos(4)];
+        endif
 
-        pbar = get (ca, "plotboxaspectratio");
-        dx = diff (__get_tight_lims__ (ca, "x"));
-        dy = diff (__get_tight_lims__ (ca, "y"));
-        dz = diff (__get_tight_lims__ (ca, "z"));
-        new_pbar = [dx dy dz];
-        new_pbar(new_pbar == 0) = 1;
-        if (dx/pbar(1) < dy/pbar(2))
-          set (ca, "xlimmode", "auto");
-          new_pbar(1) = (dy / axis_pos(4)) * axis_pos(3);
+        daratio = get (ca, "dataaspectratio");
+        if (all (daratio != [1, 1, 1]))
+          set (ca, "dataaspectratio", [1, 1, 1]);
         else
-          set (ca, "ylimmode", "auto");
-          new_pbar(2) = (dx / axis_pos(3)) * axis_pos(4);
+          set (ca, "dataaspectratio", [1+eps, 1, 1],
+                   "dataaspectratio", [1, 1, 1]);
         endif
-        set (ca, "dataaspectratio", [1, 1, 1],
-                 "plotboxaspectratio", new_pbar);
+
+        ## Matlab only adjusts plotboxaspectratio for 2-D figures, but
+        ## Octave needs to do it for 3-D as well.
+        if (is2dview)
+          set (ca, "plotboxaspectratio", pbratio);
+        else
+          pbratio = get (ca, "plotboxaspectratio");
+          if (all (pbratio != [1, 1, 1]))
+            set (ca, "plotboxaspectratio", [1, 1, 1]);
+          else
+            set (ca, "plotboxaspectratio", [1+eps, 1, 1],
+                     "plotboxaspectratio", [1, 1, 1]);
+          endif
+        endif
       elseif (strcmpi (opt, "vis3d"))
         ## Fix aspect ratio modes for rotation without stretching.
         set (ca, "dataaspectratiomode", "manual",
                  "plotboxaspectratiomode", "manual");
-
       elseif (strcmpi (opt, "normal"))
         ## Set plotboxaspectratio to something obtuse so that switching
         ## back to "auto" will force a re-calculation.