changeset 12327:2ad37783bf01 axes-layout

Move axes layout from opengl_renderer::draw_axes to axes::properties
author Konstantinos Poulios <logari81@googlemail.com>
date Thu, 03 Feb 2011 01:00:32 +0100
parents 731a0b589cab
children ad2ee858180b 383c60604085
files src/ChangeLog src/gl-render.cc src/gl-render.h src/graphics.cc src/graphics.h.in
diffstat 5 files changed, 428 insertions(+), 363 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,30 @@
+2011-02-03  Konstantinos Poulios  <logari81@googlemail.com>
+
+	* graphics.cc (axes::properties::update_axes_layout):
+	New function calculating axes layout.
+	(axes::properties::update_ticklengths): New function calculating
+	tick lengths and offsets.
+	* graphics.h.in (class axes::properties):: New private data
+	describing axes layout and corresponding "get" methods. Provide
+	declaration and call dependencies for "update_axes_layout".
+	Tag layer, yaxislocation, xaxislocation, tickdir, tickdirmode,
+	with "u" qualifier.
+	(axes::properties::update_layer,
+	axes::properties::update_yaxislocation,
+	axes::properties::update_xaxislocation,
+	axes::properties::update_ticklengths,
+	axes::properties::update_tickdir,
+	axes::properties::update_tickdirmode): New functions
+	* gl-render.cc:	(opengl_renderer::draw_axes_planes,
+	opengl_renderer::draw_axes_boxes,
+	opengl_renderer::draw_axes_x_grid,
+	opengl_renderer::draw_axes_y_grid,
+	opengl_renderer::draw_axes_z_grid,
+	opengl_renderer::draw_axes_title): Simplify arguments list.
+	(opengl_renderer::draw_axes): Remove calculation of axes layout.
+	(opengl_renderer::setup_opengl_transformation): Disable antializing.
+	* gl-render.h: Adapt functions prototypes.
+
 2011-02-01  John W. Eaton  <jwe@octave.org>
 
 	* gl-render.h (opengl_renderer::draw (const Matrix& hlist)):
--- a/src/gl-render.cc
+++ b/src/gl-render.cc
@@ -43,13 +43,6 @@
 #define CALLBACK
 #endif
 
-enum {
-  AXE_ANY_DIR   = 0,
-  AXE_DEPTH_DIR = 1,
-  AXE_HORZ_DIR  = 2,
-  AXE_VERT_DIR  = 3
-};
-
 static octave_idx_type
 xmin (octave_idx_type x, octave_idx_type y)
 {
@@ -789,52 +782,49 @@
 
   glClear (GL_DEPTH_BUFFER_BIT);
 
+  glDisable (GL_LINE_SMOOTH);
+
   // store axes transformation data
 
   xform = props.get_transform ();
 }
 
 void
-opengl_renderer::draw_axes_planes (bool visible, const Matrix& axe_color,
-                                   const Matrix& xlim, const Matrix& ylim,
-                                   const Matrix& zlim, double x_plane,
-                                   double y_plane, double z_plane)
+opengl_renderer::draw_axes_planes (const axes::properties& props)
 {
+  double xPlane = props.get_xPlane ();
+  double yPlane = props.get_yPlane ();
+  double zPlane = props.get_zPlane ();
+  double xPlaneN = props.get_xPlaneN ();
+  double yPlaneN = props.get_yPlaneN ();
+  double zPlaneN = props.get_zPlaneN ();
+
   // Axes planes
-
-  if (axe_color.numel () > 0 && visible)
+  Matrix axe_color = props.get_color_rgb ();
+  if (axe_color.numel () > 0 && props.is_visible ())
     {
       set_color (axe_color);
       set_polygon_offset (true, 2.5);
 
       glBegin (GL_QUADS);
 
-      double x_min = xlim(0);
-      double x_max = xlim(1);
-
-      double y_min = ylim(0);
-      double y_max = ylim(1);
-
-      double z_min = zlim(0);
-      double z_max = zlim(1);
-
       // X plane
-      glVertex3d (x_plane, y_min, z_min);
-      glVertex3d (x_plane, y_max, z_min);
-      glVertex3d (x_plane, y_max, z_max);
-      glVertex3d (x_plane, y_min, z_max);
+      glVertex3d (xPlane, yPlaneN, zPlaneN);
+      glVertex3d (xPlane, yPlane, zPlaneN);
+      glVertex3d (xPlane, yPlane, zPlane);
+      glVertex3d (xPlane, yPlaneN, zPlane);
 
       // Y plane
-      glVertex3d (x_min, y_plane, z_min);
-      glVertex3d (x_max, y_plane, z_min);
-      glVertex3d (x_max, y_plane, z_max);
-      glVertex3d (x_min, y_plane, z_max);
+      glVertex3d (xPlaneN, yPlane, zPlaneN);
+      glVertex3d (xPlane, yPlane, zPlaneN);
+      glVertex3d (xPlane, yPlane, zPlane);
+      glVertex3d (xPlaneN, yPlane, zPlane);
 
       // Z plane
-      glVertex3d (x_min, y_min, z_plane);
-      glVertex3d (x_max, y_min, z_plane);
-      glVertex3d (x_max, y_max, z_plane);
-      glVertex3d (x_min, y_max, z_plane);
+      glVertex3d (xPlaneN, yPlaneN, zPlane);
+      glVertex3d (xPlane, yPlaneN, zPlane);
+      glVertex3d (xPlane, yPlane, zPlane);
+      glVertex3d (xPlaneN, yPlane, zPlane);
 
       glEnd ();
 
@@ -843,19 +833,28 @@
 }
 
 void
-opengl_renderer::draw_axes_boxes (const axes::properties& props,
-                                  bool visible, bool box, bool xySym,
-                                  double xPlane, double yPlane, double zPlane,
-                                  double xPlaneN, double yPlaneN, double zPlaneN,
-                                  double xpTick, double ypTick, double zpTick,
-                                  double xpTickN, double ypTickN, double zpTickN)
+opengl_renderer::draw_axes_boxes (const axes::properties& props)
 {
+  bool xySym = props.get_xySym ();
+  double xPlane = props.get_xPlane ();
+  double yPlane = props.get_yPlane ();
+  double zPlane = props.get_zPlane ();
+  double xPlaneN = props.get_xPlaneN ();
+  double yPlaneN = props.get_yPlaneN ();
+  double zPlaneN = props.get_zPlaneN ();
+  double xpTick = props.get_xpTick ();
+  double ypTick = props.get_ypTick ();
+  double zpTick = props.get_zpTick ();
+  double xpTickN = props.get_xpTickN ();
+  double ypTickN = props.get_ypTickN ();
+  double zpTickN = props.get_zpTickN ();
+
   // Axes box
 
   set_linestyle ("-", true);
   set_linewidth (props.get_linewidth ());
 
-  if (visible)
+  if (props.is_visible ())
     {
       glBegin (GL_LINES);
 
@@ -864,7 +863,7 @@
       glVertex3d (xPlaneN, ypTick, zpTick);
       glVertex3d (xPlane, ypTick, zpTick);
 
-      if (box)
+      if (props.is_box ())
         {
           glVertex3d (xPlaneN, ypTickN, zpTick);
           glVertex3d (xPlane, ypTickN, zpTick);
@@ -879,7 +878,7 @@
       glVertex3d (xpTick, yPlaneN, zpTick);
       glVertex3d (xpTick, yPlane, zpTick);
 
-      if (box)
+      if (props.is_box ())
         {
           glVertex3d (xpTickN, yPlaneN, zpTick);
           glVertex3d (xpTickN, yPlane, zpTick);
@@ -903,7 +902,7 @@
           glVertex3d (xPlane, yPlaneN, zPlane);
         }
 
-      if (box)
+      if (props.is_box ())
         {
           glVertex3d (xPlane, yPlane, zPlaneN);
           glVertex3d (xPlane, yPlane, zPlane);
@@ -928,25 +927,35 @@
 }
 
 void
-opengl_renderer::draw_axes_x_grid (const axes::properties& props,
-                                   bool visible, bool box,
-                                   const std::string& gridstyle,
-                                   const std::string& minorgridstyle,
-                                   bool nearhoriz, double tickdir,
-                                   bool xyzSym, bool layer2Dtop,
-                                   bool x2Dtop, int xstate,
-                                   double x_min, double x_max,
-                                   double xticklen, double xtickoffset,
-                                   double fy, double yPlane, double yPlaneN,
-                                   double ypTick, double ypTickN,
-                                   double fz, int zstate, double zPlane,
-                                   double zPlaneN, double zpTick,
-                                   double zpTickN)
+opengl_renderer::draw_axes_x_grid (const axes::properties& props)
 {
+  int xstate = props.get_xstate ();
+  int zstate = props.get_zstate ();
+  bool x2Dtop = props.get_x2Dtop ();
+  bool layer2Dtop = props.get_layer2Dtop ();
+  bool xyzSym = props.get_xyzSym ();
+  bool nearhoriz = props.get_nearhoriz ();
+  double xticklen = props.get_xticklen ();
+  double xtickoffset = props.get_xtickoffset ();
+  double fy = props.get_fy ();
+  double fz = props.get_fz ();
+  double x_min = props.get_x_min ();
+  double x_max = props.get_x_max ();
+  double yPlane = props.get_yPlane ();
+  double yPlaneN = props.get_yPlaneN ();
+  double ypTick = props.get_ypTick ();
+  double ypTickN = props.get_ypTickN ();
+  double zPlane = props.get_zPlane ();
+  double zPlaneN = props.get_zPlaneN ();
+  double zpTick = props.get_zpTick ();
+  double zpTickN = props.get_zpTickN ();
+
   // X grid
 
-  if (visible && xstate != AXE_DEPTH_DIR)
+  if (props.is_visible () && xstate != AXE_DEPTH_DIR)
     {
+      std::string gridstyle = props.get_gridlinestyle ();
+      std::string minorgridstyle = props.get_minorgridlinestyle ();
       bool do_xgrid = (props.is_xgrid () && (gridstyle != "none"));
       bool do_xminorgrid = (props.is_xminorgrid () && (minorgridstyle != "none"));
       bool do_xminortick = props.is_xminortick ();
@@ -955,6 +964,7 @@
       string_vector xticklabels = props.get_xticklabel ().all_strings ();
       int wmax = 0, hmax = 0;
       bool tick_along_z = nearhoriz || xisinf (fy);
+      bool box = props.is_box ();
 
       set_color (props.get_xcolor_rgb ());
 
@@ -969,14 +979,14 @@
         {
           render_tickmarks (xticks, x_min, x_max, ypTick, ypTick,
                             zpTick, zpTickN, 0., 0.,
-                            signum(zpTick-zpTickN)*fz*xticklen*tickdir,
+                            signum(zpTick-zpTickN)*fz*xticklen,
                             0, (box && xstate != AXE_ANY_DIR));
         }
       else
         {
           render_tickmarks (xticks, x_min, x_max, ypTick, ypTickN,
                             zpTick, zpTick, 0.,
-                            signum(ypTick-ypTickN)*fy*xticklen*tickdir,
+                            signum(ypTick-ypTickN)*fy*xticklen,
                             0., 0, (box && xstate != AXE_ANY_DIR));
         }
 
@@ -1008,12 +1018,12 @@
           if (tick_along_z)
             render_tickmarks (xmticks, x_min, x_max, ypTick, ypTick,
                               zpTick, zpTickN, 0., 0.,
-                              signum(zpTick-zpTickN)*fz*xticklen/2*tickdir,
+                              signum(zpTick-zpTickN)*fz*xticklen/2,
                               0, (box && xstate != AXE_ANY_DIR));
           else
             render_tickmarks (xmticks, x_min, x_max, ypTick, ypTickN,
                               zpTick, zpTick, 0.,
-                              signum(ypTick-ypTickN)*fy*xticklen/2*tickdir,
+                              signum(ypTick-ypTickN)*fy*xticklen/2,
                               0., 0, (box && xstate != AXE_ANY_DIR));
         }
 
@@ -1093,25 +1103,35 @@
 }
 
 void
-opengl_renderer::draw_axes_y_grid (const axes::properties& props,
-                                   bool visible, bool box,
-                                   const std::string& gridstyle,
-                                   const std::string& minorgridstyle,
-                                   bool nearhoriz, double tickdir,
-                                   bool xyzSym, bool layer2Dtop,
-                                   bool y2Dright, int ystate,
-                                   double y_min, double y_max,
-                                   double yticklen, double ytickoffset,
-                                   double fx, double xPlane, double xPlaneN,
-                                   double xpTick, double xpTickN,
-                                   double fz, int zstate, double zPlane,
-                                   double zPlaneN, double zpTick,
-                                   double zpTickN)
+opengl_renderer::draw_axes_y_grid (const axes::properties& props)
 {
+  int ystate = props.get_ystate ();
+  int zstate = props.get_zstate ();
+  bool y2Dright = props.get_y2Dright ();
+  bool layer2Dtop = props.get_layer2Dtop ();
+  bool xyzSym = props.get_xyzSym ();
+  bool nearhoriz = props.get_nearhoriz ();
+  double yticklen = props.get_yticklen ();
+  double ytickoffset = props.get_ytickoffset ();
+  double fx = props.get_fx ();
+  double fz = props.get_fz ();
+  double xPlane = props.get_xPlane ();
+  double xPlaneN = props.get_xPlaneN ();
+  double xpTick = props.get_xpTick ();
+  double xpTickN = props.get_xpTickN ();
+  double y_min = props.get_y_min ();
+  double y_max = props.get_y_max ();
+  double zPlane = props.get_zPlane ();
+  double zPlaneN = props.get_zPlaneN ();
+  double zpTick = props.get_zpTick ();
+  double zpTickN = props.get_zpTickN ();
+
   // Y grid
 
-  if (ystate != AXE_DEPTH_DIR && visible)
+  if (ystate != AXE_DEPTH_DIR && props.is_visible ())
     {
+      std::string gridstyle = props.get_gridlinestyle ();
+      std::string minorgridstyle = props.get_minorgridlinestyle ();
       bool do_ygrid = (props.is_ygrid () && (gridstyle != "none"));
       bool do_yminorgrid = (props.is_yminorgrid () && (minorgridstyle != "none"));
       bool do_yminortick = props.is_yminortick ();
@@ -1120,6 +1140,7 @@
       string_vector yticklabels = props.get_yticklabel ().all_strings ();
       int wmax = 0, hmax = 0;
       bool tick_along_z = nearhoriz || xisinf (fx);
+      bool box = props.is_box ();
 
       set_color (props.get_ycolor_rgb ());
 
@@ -1133,12 +1154,12 @@
       if (tick_along_z)
         render_tickmarks (yticks, y_min, y_max, xpTick, xpTick,
                           zpTick, zpTickN, 0., 0.,
-                          signum(zpTick-zpTickN)*fz*yticklen*tickdir,
+                          signum(zpTick-zpTickN)*fz*yticklen,
                           1, (box && ystate != AXE_ANY_DIR));
       else
         render_tickmarks (yticks, y_min, y_max, xpTick, xpTickN,
                           zpTick, zpTick,
-                          signum(xPlaneN-xPlane)*fx*yticklen*tickdir,
+                          signum(xPlaneN-xPlane)*fx*yticklen,
                           0., 0., 1, (box && ystate != AXE_ANY_DIR));
 
       // tick texts
@@ -1170,12 +1191,12 @@
           if (tick_along_z)
             render_tickmarks (ymticks, y_min, y_max, xpTick, xpTick,
                               zpTick, zpTickN, 0., 0.,
-                              signum(zpTick-zpTickN)*fz*yticklen/2*tickdir,
+                              signum(zpTick-zpTickN)*fz*yticklen/2,
                               1, (box && ystate != AXE_ANY_DIR));
           else
             render_tickmarks (ymticks, y_min, y_max, xpTick, xpTickN,
                               zpTick, zpTick,
-                              signum(xpTick-xpTickN)*fx*yticklen/2*tickdir,
+                              signum(xpTick-xpTickN)*fx*yticklen/2,
                               0., 0., 1, (box && ystate != AXE_ANY_DIR));
         }
 
@@ -1253,20 +1274,28 @@
 }
 
 void
-opengl_renderer::draw_axes_z_grid (const axes::properties& props,
-                                   bool visible, bool box,
-                                   const std::string& gridstyle,
-                                   const std::string& minorgridstyle,
-                                   double tickdir, bool xySym, bool zSign,
-                                   int zstate, double z_min, double z_max,
-                                   double zticklen, double ztickoffset,
-                                   double fx, double xPlane, double xPlaneN,
-                                   double fy, double yPlane, double yPlaneN)
+opengl_renderer::draw_axes_z_grid (const axes::properties& props)
 {
+  int zstate = props.get_zstate ();
+  bool xySym = props.get_xySym ();
+  bool zSign = props.get_zSign ();
+  double zticklen = props.get_zticklen ();
+  double ztickoffset = props.get_ztickoffset ();
+  double fx = props.get_fx ();
+  double fy = props.get_fy ();
+  double xPlane = props.get_xPlane ();
+  double xPlaneN = props.get_xPlaneN ();
+  double yPlane = props.get_yPlane ();
+  double yPlaneN = props.get_yPlaneN ();
+  double z_min = props.get_z_min ();
+  double z_max = props.get_z_max ();
+
   // Z Grid
 
-  if (zstate != AXE_DEPTH_DIR && visible)
+  if (zstate != AXE_DEPTH_DIR && props.is_visible ())
     {
+      std::string gridstyle = props.get_gridlinestyle ();
+      std::string minorgridstyle = props.get_minorgridlinestyle ();
       bool do_zgrid = (props.is_zgrid () && (gridstyle != "none"));
       bool do_zminorgrid = (props.is_zminorgrid () && (minorgridstyle != "none"));
       bool do_zminortick = props.is_zminortick ();
@@ -1274,6 +1303,7 @@
       Matrix zmticks = xform.zscale (props.get_zmtick ().matrix_value ());
       string_vector zticklabels = props.get_zticklabel ().all_strings ();
       int wmax = 0, hmax = 0;
+      bool box = props.is_box ();
 
       set_color (props.get_zcolor_rgb ());
 
@@ -1288,12 +1318,12 @@
           if (xisinf (fy))
             render_tickmarks (zticks, z_min, z_max, xPlaneN, xPlane,
                               yPlane, yPlane,
-                              signum(xPlaneN-xPlane)*fx*zticklen*tickdir,
+                              signum(xPlaneN-xPlane)*fx*zticklen,
                               0., 0., 2, (box && zstate != AXE_ANY_DIR));
           else
             render_tickmarks (zticks, z_min, z_max, xPlaneN, xPlaneN,
                               yPlane, yPlane, 0.,
-                              signum(yPlane-yPlaneN)*fy*zticklen*tickdir,
+                              signum(yPlane-yPlaneN)*fy*zticklen,
                               0., 2, false);
         }
       else
@@ -1301,12 +1331,12 @@
           if (xisinf (fx))
             render_tickmarks (zticks, z_min, z_max, xPlaneN, xPlane,
                               yPlaneN, yPlane, 0.,
-                              signum(yPlaneN-yPlane)*fy*zticklen*tickdir,
+                              signum(yPlaneN-yPlane)*fy*zticklen,
                               0., 2, (box && zstate != AXE_ANY_DIR));
           else
             render_tickmarks (zticks, z_min, z_max, xPlane, xPlane,
                               yPlaneN, yPlane,
-                              signum(xPlane-xPlaneN)*fx*zticklen*tickdir,
+                              signum(xPlane-xPlaneN)*fx*zticklen,
                               0., 0., 2, false);
         }
 
@@ -1353,12 +1383,12 @@
               if (xisinf (fy))
                 render_tickmarks (zmticks, z_min, z_max, xPlaneN, xPlane,
                                   yPlane, yPlane,
-                                  signum(xPlaneN-xPlane)*fx*zticklen/2*tickdir,
+                                  signum(xPlaneN-xPlane)*fx*zticklen/2,
                                   0., 0., 2, (box && zstate != AXE_ANY_DIR));
               else
                 render_tickmarks (zmticks, z_min, z_max, xPlaneN, xPlaneN,
                                   yPlane, yPlane, 0.,
-                                  signum(yPlane-yPlaneN)*fy*zticklen/2*tickdir,
+                                  signum(yPlane-yPlaneN)*fy*zticklen/2,
                                   0., 2, false);
             }
           else
@@ -1366,12 +1396,12 @@
               if (xisinf (fx))
                 render_tickmarks (zmticks, z_min, z_max, xPlane, xPlane,
                                   yPlaneN, yPlane, 0.,
-                                  signum(yPlaneN-yPlane)*fy*zticklen/2*tickdir,
+                                  signum(yPlaneN-yPlane)*fy*zticklen/2,
                                   0., 2, (box && zstate != AXE_ANY_DIR));
               else
                 render_tickmarks (zmticks, z_min, z_max, xPlane, xPlane,
                                   yPlaneN, yPlaneN,
-                                  signum(xPlane-xPlaneN)*fx*zticklen/2*tickdir,
+                                  signum(xPlane-xPlaneN)*fx*zticklen/2,
                                   0., 0., 2, false);
             }            
         }
@@ -1475,13 +1505,18 @@
 }
 
 void
-opengl_renderer::draw_axes_title (const axes::properties& props,
-                                  double x_min, double x_max,
-                                  double y_min, double y_max,
-                                  double z_min, double z_max)
+opengl_renderer::draw_axes_title (const axes::properties& props)
 {
+  double x_min = props.get_x_min ();
+  double x_max = props.get_x_max ();
+  double y_min = props.get_y_min ();
+  double y_max = props.get_y_max ();
+  double z_min = props.get_z_min ();
+  double z_max = props.get_z_max ();
+
   // Title
 
+  // FIXME: bbox has to be moved to axes::properties
   ColumnVector bbox(4);
   bbox(0) = octave_Inf;
   bbox(1) = octave_Inf;
@@ -1531,8 +1566,6 @@
 
   if (antialias == GL_TRUE)
     glEnable (GL_LINE_SMOOTH);
-  else
-    glDisable (GL_LINE_SMOOTH);
 
   Matrix children = props.get_all_children ();
   std::list<graphics_object> obj_list;
@@ -1603,205 +1636,18 @@
 
   // draw axes object
 
-  const Matrix xlim = xform.xscale (props.get_xlim ().matrix_value ());
-  const Matrix ylim = xform.yscale (props.get_ylim ().matrix_value ());
-  const Matrix zlim = xform.zscale (props.get_zlim ().matrix_value ());
-
-  double x_min = xlim(0), x_max = xlim(1);
-  double y_min = ylim(0), y_max = ylim(1);
-  double z_min = zlim(0), z_max = zlim(1);
-
-  double xd = (props.xdir_is ("normal") ? 1 : -1);
-  double yd = (props.ydir_is ("normal") ? 1 : -1);
-  double zd = (props.zdir_is ("normal") ? 1 : -1);
-
-  ColumnVector p1, p2, xv (3), yv (3), zv (3);
-  int xstate, ystate, zstate;
-
-  xstate = ystate = zstate = AXE_ANY_DIR;
-
-  p1 = xform.transform (x_min, (y_min+y_max)/2, (z_min+z_max)/2, false);
-  p2 = xform.transform (x_max, (y_min+y_max)/2, (z_min+z_max)/2, false);
-  xv(0) = xround (p2(0)-p1(0));
-  xv(1) = xround (p2(1)-p1(1));
-  xv(2) = (p2(2)-p1(2));
-  if (xv(0) == 0 && xv(1) == 0)
-    xstate = AXE_DEPTH_DIR;
-  else if (xv(2) == 0)
-    {
-      if (xv(0) == 0)
-        xstate = AXE_VERT_DIR;
-      else if (xv(1) == 0)
-        xstate = AXE_HORZ_DIR;
-    }
-  double xPlane;
-  if (xv(2) == 0)
-    if (xv(1) == 0)
-      xPlane = (xv(0) > 0 ? x_max : x_min);
-    else
-      xPlane = (xv(1) < 0 ? x_max : x_min);
-  else
-    xPlane = (xv(2) < 0 ? x_min : x_max);
-  double xPlaneN = (xPlane == x_min ? x_max : x_min);
-  double fx = (x_max-x_min)/sqrt(xv(0)*xv(0)+xv(1)*xv(1));
-
-  p1 = xform.transform ((x_min+x_max)/2, y_min, (z_min+z_max)/2, false);
-  p2 = xform.transform ((x_min+x_max)/2, y_max, (z_min+z_max)/2, false);
-  yv(0) = xround (p2(0)-p1(0));
-  yv(1) = xround (p2(1)-p1(1));
-  yv(2) = (p2(2)-p1(2));
-  if (yv(0) == 0 && yv(1) == 0)
-    ystate = AXE_DEPTH_DIR;
-  else if (yv(2) == 0)
-    {
-      if (yv(0) == 0)
-        ystate = AXE_VERT_DIR;
-      else if (yv(1) == 0)
-        ystate = AXE_HORZ_DIR;
-    }
-  double yPlane;
-  if (yv(2) == 0)
-    if (yv(1) == 0)
-      yPlane = (yv(0) > 0 ? y_max : y_min);
-    else
-      yPlane = (yv(1) < 0 ? y_max : y_min);
-  else
-    yPlane = (yv(2) < 0 ? y_min : y_max);
-  double yPlaneN = (yPlane == y_min ? y_max : y_min);
-  double fy = (y_max-y_min)/sqrt(yv(0)*yv(0)+yv(1)*yv(1));
-
-  p1 = xform.transform((x_min+x_max)/2, (y_min+y_max)/2, z_min, false);
-  p2 = xform.transform((x_min+x_max)/2, (y_min+y_max)/2, z_max, false);
-  zv(0) = xround(p2(0)-p1(0));
-  zv(1) = xround (p2(1)-p1(1));
-  zv(2) = (p2(2)-p1(2));
-  if (zv(0) == 0 && zv(1) == 0)
-    zstate = AXE_DEPTH_DIR;
-  else if (zv(2) == 0)
-  {
-    if (zv(0) == 0)
-      zstate = AXE_VERT_DIR;
-    else if (zv(1) == 0)
-      zstate = AXE_HORZ_DIR;
-  }
-  double zPlane;
-  if (zv(2) == 0)
-    if (zv(1) == 0)
-      zPlane = (zv(0) > 0 ? z_min : z_max);
-    else
-      zPlane = (zv(1) < 0 ? z_min : z_max);
-  else
-    zPlane = (zv(2) < 0 ? z_min : z_max);
-  double zPlaneN = (zPlane == z_min ? z_max : z_min);
-  double fz = (z_max-z_min)/sqrt(zv(0)*zv(0)+zv(1)*zv(1));
-
-  bool mode2d = (((xstate > AXE_DEPTH_DIR ? 1 : 0) +
-        (ystate > AXE_DEPTH_DIR ? 1 : 0) +
-        (zstate > AXE_DEPTH_DIR ? 1 : 0)) == 2);
-  if (props.tickdirmode_is ("auto"))
-  {
-    // FIXME: tickdir should be updated (code below comes
-    //        from JHandles)
-    //autoMode++;
-    //TickDir.set(mode2d ? "in" : "out", true);
-    //autoMode--;
-  }
-
-  // FIXME: use ticklength property
-  double xticklen = 7, yticklen = 7, zticklen = 7;
-
-  //double tickdir = (props.tickdir_is ("in") ? -1 : 1);
-  double tickdir = (props.tickdirmode_is ("auto") ?
-                    (mode2d ? -1 : 1) :
-                    (props.tickdir_is ("in") ? -1 : 1));
-  double xtickoffset = (mode2d && tickdir < 0 ? 0 : xticklen) + 5;
-  double ytickoffset = (mode2d && tickdir < 0 ? 0 : yticklen) + 5;
-  double ztickoffset = (mode2d && tickdir < 0 ? 0 : zticklen) + 5;
-
-  bool xySym = (xd*yd*(xPlane-xPlaneN)*(yPlane-yPlaneN) > 0);
-  bool x2Dtop = false;
-  bool y2Dright = false;
-  bool layer2Dtop = false;
-  bool zSign = (zd*(zPlane-zPlaneN) <= 0);
-  bool xyzSym = zSign ? xySym : !xySym;
-  double xpTick = (zSign ? xPlaneN : xPlane);
-  double ypTick = (zSign ? yPlaneN : yPlane);
-  double zpTick = (zSign ? zPlane : zPlaneN);
-  double xpTickN = (zSign ? xPlane : xPlaneN);
-  double ypTickN = (zSign ? yPlane : yPlaneN);
-  double zpTickN = (zSign ? zPlaneN : zPlane);
-
-  /* 2D mode */
-  if (xstate == AXE_HORZ_DIR && ystate == AXE_VERT_DIR)
-  {
-    if (props.xaxislocation_is ("top"))
-    {
-      double tmp = yPlane;
-      yPlane = yPlaneN;
-      yPlaneN = tmp;
-      x2Dtop = true;
-    }
-    ypTick = yPlaneN;
-    ypTickN = yPlane;
-    if (props.yaxislocation_is ("right"))
-    {
-      double tmp = xPlane;
-      xPlane = xPlaneN;
-      xPlaneN = tmp;
-      y2Dright = true;
-    }
-    xpTick = xPlaneN;
-    xpTickN = xPlane;
-    if (props.layer_is ("top"))
-      {
-        zpTick = zPlaneN;
-        layer2Dtop = true;
-      }
-    else
-      zpTick = zPlane;
-  }
-
-  Matrix view = props.get_view ().matrix_value ();
-  bool nearhoriz = std::abs(view(1)) <= 5;
-
-  Matrix axe_color = props.get_color_rgb ();
-  bool visible = props.is_visible ();
-  bool box = props.is_box ();
-
-  draw_axes_planes (visible, axe_color, xlim, ylim, zlim,
-                    xPlane, yPlane, zPlane);
-
-  draw_axes_boxes (props, visible, box, xySym, xPlane, yPlane, zPlane,
-                   xPlaneN, yPlaneN, zPlaneN, xpTick, ypTick, zpTick,
-                   xpTickN, ypTickN, zpTickN);
-
-
-  std::string gridstyle = props.get_gridlinestyle ();
-  std::string minorgridstyle = props.get_minorgridlinestyle ();
+  draw_axes_planes (props);
+  draw_axes_boxes (props);
 
   set_font (props);
 
-  draw_axes_x_grid (props, visible, box, gridstyle, minorgridstyle,
-                    nearhoriz, tickdir, xyzSym, layer2Dtop, x2Dtop,
-                    xstate, xlim(0), xlim(1), xticklen, xtickoffset,
-                    fy, yPlane, yPlaneN, ypTick, ypTickN,
-                    fz, zstate, zPlane, zPlaneN, zpTick, zpTickN);
-
-  draw_axes_y_grid (props, visible, box, gridstyle, minorgridstyle,
-                    nearhoriz, tickdir, xyzSym, layer2Dtop, y2Dright,
-                    ystate, ylim(0), ylim(1), yticklen, ytickoffset,
-                    fx, xPlane, xPlaneN, xpTick, xpTickN,
-                    fz, zstate, zPlane, zPlaneN, zpTick, zpTickN);
-
-  draw_axes_z_grid (props, visible, box, gridstyle, minorgridstyle,
-                    tickdir, xySym, zSign, zstate, zlim(0), zlim(1),
-                    zticklen, ztickoffset, fx, xPlane, xPlaneN,
-                    fy, yPlane, yPlaneN);
+  draw_axes_x_grid (props);
+  draw_axes_y_grid (props);
+  draw_axes_z_grid (props);
 
   set_linestyle ("-");
 
-  draw_axes_title (props, xlim(0), xlim(1), ylim(0), ylim(1),
-                   zlim(0), zlim(1));
+  draw_axes_title (props);
 
   draw_axes_children (props);
 }
--- a/src/gl-render.h
+++ b/src/gl-render.h
@@ -166,63 +166,14 @@
 
   void setup_opengl_transformation (const axes::properties& props);
 
-  void draw_axes_planes (bool visible, const Matrix& axe_color,
-                         const Matrix& xlim, const Matrix& ylim,
-                         const Matrix& zlim, double x_plane,
-                         double y_plane, double z_plane);
-
-  void draw_axes_boxes (const axes::properties& props,
-                        bool visible, bool box, bool xySym,
-                        double xPlane, double yPlane, double zPlane,
-                        double xPlaneN, double yPlaneN, double zPlaneN,
-                        double xpTick, double ypTick, double zpTick,
-                        double xpTickN, double ypTickN, double zpTickN);
-
-  void draw_axes_x_grid (const axes::properties& props,
-                         bool visible, bool box,
-                         const std::string& gridstyle,
-                         const std::string& minorgridstyle,
-                         bool nearhoriz, double tickdir,
-                         bool xyzSym, bool layer2Dtop,
-                         bool x2Dtop, int xstate,
-                         double x_min, double x_max,
-                         double xticklen, double xtickoffset,
-                         double fy, double yPlane, double yPlaneN,
-                         double ypTick, double ypTickN,
-                         double fz, int zstate, double zPlane,
-                         double zPlaneN, double zpTick,
-                         double zpTickN);
+  void draw_axes_planes (const axes::properties& props);
+  void draw_axes_boxes (const axes::properties& props);
 
-  void draw_axes_y_grid (const axes::properties& props,
-                         bool visible, bool box,
-                         const std::string& gridstyle,
-                         const std::string& minorgridstyle,
-                         bool nearhoriz, double tickdir,
-                         bool xyzSym, bool layer2Dtop,
-                         bool y2Dright, int ystate,
-                         double y_min, double y_max,
-                         double yticklen, double ytickoffset,
-                         double fx, double xPlane, double xPlaneN,
-                         double xpTick, double xpTickN,
-                         double fz, int zstate, double zPlane,
-                         double zPlaneN, double zpTick,
-                         double zpTickN);
+  void draw_axes_x_grid (const axes::properties& props);
+  void draw_axes_y_grid (const axes::properties& props);
+  void draw_axes_z_grid (const axes::properties& props);
 
-  void draw_axes_z_grid (const axes::properties& props,
-                         bool visible, bool box,
-                         const std::string& gridstyle,
-                         const std::string& minorgridstyle,
-                         double tickdir, bool xySym, bool zSign,
-                         int zstate, double z_min, double z_max,
-                         double zticklen, double ztickoffset,
-                         double fx, double xPlane, double xPlaneN,
-                         double fy, double yPlane, double yPlaneN);
-
-  void draw_axes_title (const axes::properties& props,
-                        double x_min, double x_max,
-                        double y_min, double y_max,
-                        double z_min, double z_max);
-
+  void draw_axes_title (const axes::properties& props);
   void draw_axes_children (const axes::properties& props);
 
 private:
--- a/src/graphics.cc
+++ b/src/graphics.cc
@@ -3895,6 +3895,176 @@
   x_gl_mat2 = x_viewport * x_projection;
 }
 
+void
+axes::properties::update_axes_layout (void)
+{
+  graphics_xform xform = get_transform ();
+
+  double xd = (xdir_is ("normal") ? 1 : -1);
+  double yd = (ydir_is ("normal") ? 1 : -1);
+  double zd = (zdir_is ("normal") ? 1 : -1);
+
+  const Matrix xlims = xform.xscale (get_xlim ().matrix_value ());
+  const Matrix ylims = xform.yscale (get_ylim ().matrix_value ());
+  const Matrix zlims = xform.zscale (get_zlim ().matrix_value ());
+  double x_min = xlims(0), x_max = xlims(1);
+  double y_min = ylims(0), y_max = ylims(1);
+  double z_min = zlims(0), z_max = zlims(1);
+
+  ColumnVector p1, p2, dir (3);
+
+  xstate = ystate = zstate = AXE_ANY_DIR;
+
+  p1 = xform.transform (x_min, (y_min+y_max)/2, (z_min+z_max)/2, false);
+  p2 = xform.transform (x_max, (y_min+y_max)/2, (z_min+z_max)/2, false);
+  dir(0) = xround (p2(0)-p1(0));
+  dir(1) = xround (p2(1)-p1(1));
+  dir(2) = (p2(2)-p1(2));
+  if (dir(0) == 0 && dir(1) == 0)
+    xstate = AXE_DEPTH_DIR;
+  else if (dir(2) == 0)
+    {
+      if (dir(0) == 0)
+        xstate = AXE_VERT_DIR;
+      else if (dir(1) == 0)
+        xstate = AXE_HORZ_DIR;
+    }
+  if (dir(2) == 0)
+    if (dir(1) == 0)
+      xPlane = (dir(0) > 0 ? x_max : x_min);
+    else
+      xPlane = (dir(1) < 0 ? x_max : x_min);
+  else
+    xPlane = (dir(2) < 0 ? x_min : x_max);
+  xPlaneN = (xPlane == x_min ? x_max : x_min);
+  fx = (x_max-x_min)/sqrt(dir(0)*dir(0)+dir(1)*dir(1));
+
+  p1 = xform.transform ((x_min+x_max)/2, y_min, (z_min+z_max)/2, false);
+  p2 = xform.transform ((x_min+x_max)/2, y_max, (z_min+z_max)/2, false);
+  dir(0) = xround (p2(0)-p1(0));
+  dir(1) = xround (p2(1)-p1(1));
+  dir(2) = (p2(2)-p1(2));
+  if (dir(0) == 0 && dir(1) == 0)
+    ystate = AXE_DEPTH_DIR;
+  else if (dir(2) == 0)
+    {
+      if (dir(0) == 0)
+        ystate = AXE_VERT_DIR;
+      else if (dir(1) == 0)
+        ystate = AXE_HORZ_DIR;
+    }
+  if (dir(2) == 0)
+    if (dir(1) == 0)
+      yPlane = (dir(0) > 0 ? y_max : y_min);
+    else
+      yPlane = (dir(1) < 0 ? y_max : y_min);
+  else
+    yPlane = (dir(2) < 0 ? y_min : y_max);
+  yPlaneN = (yPlane == y_min ? y_max : y_min);
+  fy = (y_max-y_min)/sqrt(dir(0)*dir(0)+dir(1)*dir(1));
+
+  p1 = xform.transform((x_min+x_max)/2, (y_min+y_max)/2, z_min, false);
+  p2 = xform.transform((x_min+x_max)/2, (y_min+y_max)/2, z_max, false);
+  dir(0) = xround(p2(0)-p1(0));
+  dir(1) = xround (p2(1)-p1(1));
+  dir(2) = (p2(2)-p1(2));
+  if (dir(0) == 0 && dir(1) == 0)
+    zstate = AXE_DEPTH_DIR;
+  else if (dir(2) == 0)
+  {
+    if (dir(0) == 0)
+      zstate = AXE_VERT_DIR;
+    else if (dir(1) == 0)
+      zstate = AXE_HORZ_DIR;
+  }
+  if (dir(2) == 0)
+    if (dir(1) == 0)
+      zPlane = (dir(0) > 0 ? z_min : z_max);
+    else
+      zPlane = (dir(1) < 0 ? z_min : z_max);
+  else
+    zPlane = (dir(2) < 0 ? z_min : z_max);
+  zPlaneN = (zPlane == z_min ? z_max : z_min);
+  fz = (z_max-z_min)/sqrt(dir(0)*dir(0)+dir(1)*dir(1));
+
+  update_ticklengths ();
+
+  xySym = (xd*yd*(xPlane-xPlaneN)*(yPlane-yPlaneN) > 0);
+  zSign = (zd*(zPlane-zPlaneN) <= 0);
+  xyzSym = zSign ? xySym : !xySym;
+  xpTick = (zSign ? xPlaneN : xPlane);
+  ypTick = (zSign ? yPlaneN : yPlane);
+  zpTick = (zSign ? zPlane : zPlaneN);
+  xpTickN = (zSign ? xPlane : xPlaneN);
+  ypTickN = (zSign ? yPlane : yPlaneN);
+  zpTickN = (zSign ? zPlaneN : zPlane);
+
+  /* 2D mode */
+  x2Dtop = false;
+  y2Dright = false;
+  layer2Dtop = false;
+  if (xstate == AXE_HORZ_DIR && ystate == AXE_VERT_DIR)
+  {
+    if (xaxislocation_is ("top"))
+    {
+      double tmp = yPlane;
+      yPlane = yPlaneN;
+      yPlaneN = tmp;
+      x2Dtop = true;
+    }
+    ypTick = yPlaneN;
+    ypTickN = yPlane;
+    if (yaxislocation_is ("right"))
+    {
+      double tmp = xPlane;
+      xPlane = xPlaneN;
+      xPlaneN = tmp;
+      y2Dright = true;
+    }
+    xpTick = xPlaneN;
+    xpTickN = xPlane;
+    if (layer_is ("top"))
+      {
+        zpTick = zPlaneN;
+        layer2Dtop = true;
+      }
+    else
+      zpTick = zPlane;
+  }
+
+  Matrix viewmat = get_view ().matrix_value ();
+  nearhoriz = std::abs(viewmat(1)) <= 5;
+}
+
+void
+axes::properties::update_ticklengths (void)
+{
+  bool mode2d = (((xstate > AXE_DEPTH_DIR ? 1 : 0) +
+                  (ystate > AXE_DEPTH_DIR ? 1 : 0) +
+                  (zstate > AXE_DEPTH_DIR ? 1 : 0)) == 2);
+  if (tickdirmode_is ("auto"))
+  {
+    // FIXME: tickdir should be updated (code below comes
+    //        from JHandles)
+    //autoMode++;
+    //TickDir.set(mode2d ? "in" : "out", true);
+    //autoMode--;
+  }
+
+  //double ticksign = (tickdir_is ("in") ? -1 : 1);
+  double ticksign = (tickdirmode_is ("auto") ?
+                     (mode2d ? -1 : 1) :
+                     (tickdir_is ("in") ? -1 : 1));
+  // FIXME: use ticklength property
+  xticklen = ticksign*7;
+  yticklen = ticksign*7;
+  zticklen = ticksign*7;
+
+  xtickoffset = (mode2d ? std::max (0., xticklen) : std::abs (xticklen)) + 5;
+  ytickoffset = (mode2d ? std::max (0., yticklen) : std::abs (yticklen)) + 5;
+  ztickoffset = (mode2d ? std::max (0., zticklen) : std::abs (zticklen)) + 5;
+}
+
 static void
 normalized_aspectratios (Matrix& aspectratios, const Matrix& scalefactors,
                          double xlength, double ylength, double zlength)
--- a/src/graphics.h.in
+++ b/src/graphics.h.in
@@ -3053,6 +3053,13 @@
   Matrix zlim;
 };
 
+enum {
+  AXE_ANY_DIR   = 0,
+  AXE_DEPTH_DIR = 1,
+  AXE_HORZ_DIR  = 2,
+  AXE_VERT_DIR  = 3
+};
+
 class OCTINTERP_API axes : public base_graphics_object
 {
 public:
@@ -3079,11 +3086,13 @@
       }
 
     void update_camera (void);
+    void update_axes_layout (void);
     void update_aspectratios (void);
     void update_transform (void)
       {
         update_aspectratios ();
         update_camera ();
+        update_axes_layout ();
       }
 
     graphics_xform get_transform (void) const
@@ -3095,6 +3104,44 @@
     Matrix get_opengl_matrix_2 (void) const { return x_gl_mat2; }
     Matrix get_transform_zlim (void) const { return x_zlim; }
 
+    int get_xstate (void) const { return xstate; }
+    int get_ystate (void) const { return ystate; }
+    int get_zstate (void) const { return zstate; }
+    double get_xPlane (void) const { return xPlane; }
+    double get_xPlaneN (void) const { return xPlaneN; }
+    double get_yPlane (void) const { return yPlane; }
+    double get_yPlaneN (void) const { return yPlaneN; }
+    double get_zPlane (void) const { return zPlane; }
+    double get_zPlaneN (void) const { return zPlaneN; }
+    double get_xpTick (void) const { return xpTick; }
+    double get_xpTickN (void) const { return xpTickN; }
+    double get_ypTick (void) const { return ypTick; }
+    double get_ypTickN (void) const { return ypTickN; }
+    double get_zpTick (void) const { return zpTick; }
+    double get_zpTickN (void) const { return zpTickN; }
+    double get_x_min (void) const { return std::min (xPlane, xPlaneN); }
+    double get_x_max (void) const { return std::max (xPlane, xPlaneN); }
+    double get_y_min (void) const { return std::min (yPlane, yPlaneN); }
+    double get_y_max (void) const { return std::max (yPlane, yPlaneN); }
+    double get_z_min (void) const { return std::min (zPlane, zPlaneN); }
+    double get_z_max (void) const { return std::max (zPlane, zPlaneN); }
+    double get_fx (void) const { return fx; }
+    double get_fy (void) const { return fy; }
+    double get_fz (void) const { return fz; }
+    double get_xticklen (void) const { return xticklen; }
+    double get_yticklen (void) const { return yticklen; }
+    double get_zticklen (void) const { return zticklen; }
+    double get_xtickoffset (void) const { return xtickoffset; }
+    double get_ytickoffset (void) const { return ytickoffset; }
+    double get_ztickoffset (void) const { return ztickoffset; }
+    bool get_x2Dtop (void) const { return x2Dtop; }
+    bool get_y2Dright (void) const { return y2Dright; }
+    bool get_layer2Dtop (void) const { return layer2Dtop; }
+    bool get_xySym (void) const { return xySym; }
+    bool get_xyzSym (void) const { return xyzSym; }
+    bool get_zSign (void) const { return zSign; }
+    bool get_nearhoriz (void) const { return nearhoriz; }
+
     ColumnVector pixel2coord (double px, double py) const
     { return get_transform ().untransform (px, py, (x_zlim(0)+x_zlim(1))/2); }
 
@@ -3120,6 +3167,16 @@
     Matrix x_zlim;
     std::list<octave_value> zoom_stack;
 
+    // Axes layout data
+    int xstate, ystate, zstate;
+    double xPlane, xPlaneN, yPlane, yPlaneN, zPlane, zPlaneN;
+    double xpTick, xpTickN, ypTick, ypTickN, zpTick, zpTickN;
+    double fx, fy, fz;
+    double xticklen, yticklen, zticklen;
+    double xtickoffset, ytickoffset, ztickoffset;
+    bool x2Dtop, y2Dright, layer2Dtop;
+    bool xySym, xyzSym, zSign, nearhoriz;
+
     void set_text_child (handle_property& h, const std::string& who,
                          const octave_value& v);
 
@@ -3136,7 +3193,7 @@
       array_property colororder , default_colororder ()
       array_property dataaspectratio mu , Matrix (1, 3, 1.0)
       radio_property dataaspectratiomode u , "{auto}|manual"
-      radio_property layer , "{bottom}|top"
+      radio_property layer u , "{bottom}|top"
       row_vector_property xlim mu , default_lim ()
       row_vector_property ylim mu , default_lim ()
       row_vector_property zlim mu , default_lim ()
@@ -3184,8 +3241,8 @@
       radio_property xdir u , "{normal}|reverse"
       radio_property ydir u , "{normal}|reverse"
       radio_property zdir u , "{normal}|reverse"
-      radio_property yaxislocation , "{left}|right|zero"
-      radio_property xaxislocation , "{bottom}|top|zero"
+      radio_property yaxislocation u , "{left}|right|zero"
+      radio_property xaxislocation u , "{bottom}|top|zero"
       array_property view u , Matrix ()
       bool_property __hold_all__ h , "off"
       radio_property nextplot , "new|add|replacechildren|{replace}"
@@ -3214,8 +3271,8 @@
       array_property plotboxaspectratio mu , Matrix (1, 3, 1.0)
       radio_property plotboxaspectratiomode u , "{auto}|manual"
       radio_property projection , "{orthographic}|perpective"
-      radio_property tickdir m , "{in}|out"
-      radio_property tickdirmode , "{auto}|manual"
+      radio_property tickdir mu , "{in}|out"
+      radio_property tickdirmode u , "{auto}|manual"
       array_property ticklength , default_axes_ticklength ()
       array_property tightinset r , Matrix (1, 4, 0.0)
       // FIXME -- uicontextmenu should be moved here.
@@ -3240,15 +3297,23 @@
     void update_yscale (void) { sy = get_yscale (); }
     void update_zscale (void) { sz = get_zscale (); }
 
-    void update_view (void) { update_camera (); }
+    void update_view (void) { update_camera (); update_axes_layout (); }
     void update_dataaspectratio (void) { update_transform (); }
     void update_dataaspectratiomode (void) { update_transform (); }
     void update_plotboxaspectratio (void) { update_transform (); }
     void update_plotboxaspectratiomode (void) { update_transform (); }
 
-    void update_xdir (void) { update_camera (); }
-    void update_ydir (void) { update_camera (); }
-    void update_zdir (void) { update_camera (); }
+    void update_layer (void) { update_axes_layout (); }
+    void update_yaxislocation (void) { update_axes_layout (); }
+    void update_xaxislocation (void) { update_axes_layout (); }
+
+    void update_xdir (void) { update_camera (); update_axes_layout (); }
+    void update_ydir (void) { update_camera (); update_axes_layout (); }
+    void update_zdir (void) { update_camera (); update_axes_layout (); }
+
+    void update_ticklengths (void);
+    void update_tickdir (void) { update_ticklengths (); }
+    void update_tickdirmode (void) { update_ticklengths (); }
 
     void update_xtick (void)
       {
@@ -3349,6 +3414,8 @@
 
       if (do_clr_zoom)
         zoom_stack.clear ();
+
+      update_axes_layout ();
     }
 
     void update_ylim (bool do_clr_zoom = true)
@@ -3362,6 +3429,8 @@
 
       if (do_clr_zoom)
         zoom_stack.clear ();
+
+      update_axes_layout ();
     }
 
     void update_zlim (void)
@@ -3374,6 +3443,8 @@
       fix_limits (zlim);
 
       zoom_stack.clear ();
+
+      update_axes_layout ();
     }
 
   };