scripts/plot/axis.m
author Rik <rdrider0-list@yahoo.com>
Wed May 27 13:06:38 2009 -0700 (2009-05-27)
changeset 9277 be84e9654feb
parent 9209 923c7cb7f13f
child 9319 d6052da689e2
permissions -rw-r--r--
Update axis.m documentation to reflect addition of "tight" option.
     1 ## Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2002, 2003, 2004,
     2 ##               2005, 2006, 2007, 2008, 2009 John W. Eaton
     3 ##
     4 ## This file is part of Octave.
     5 ##
     6 ## Octave is free software; you can redistribute it and/or modify it
     7 ## under the terms of the GNU General Public License as published by
     8 ## the Free Software Foundation; either version 3 of the License, or (at
     9 ## your option) any later version.
    10 ##
    11 ## Octave is distributed in the hope that it will be useful, but
    12 ## WITHOUT ANY WARRANTY; without even the implied warranty of
    13 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    14 ## General Public License for more details.
    15 ##
    16 ## You should have received a copy of the GNU General Public License
    17 ## along with Octave; see the file COPYING.  If not, see
    18 ## <http://www.gnu.org/licenses/>.
    19 
    20 ## -*- texinfo -*-
    21 ## @deftypefn {Function File} {} axis (@var{limits})
    22 ## Set axis limits for plots.
    23 ##
    24 ## The argument @var{limits} should be a 2, 4, or 6 element vector.  The
    25 ## first and second elements specify the lower and upper limits for the x
    26 ## axis.  The third and fourth specify the limits for the y-axis, and the
    27 ## fifth and sixth specify the limits for the z-axis.
    28 ##
    29 ## Without any arguments, @code{axis} turns autoscaling on.  
    30 ##
    31 ## With one output argument, @code{x = axis} returns the current axes 
    32 ##
    33 ## The vector argument specifying limits is optional, and additional
    34 ## string arguments may be used to specify various axis properties.  For
    35 ## example,
    36 ##
    37 ## @example
    38 ## axis ([1, 2, 3, 4], "square");
    39 ## @end example
    40 ##
    41 ## @noindent
    42 ## forces a square aspect ratio, and
    43 ##
    44 ## @example
    45 ## axis ("labely", "tic");
    46 ## @end example
    47 ##
    48 ## @noindent
    49 ## turns tic marks on for all axes and tic mark labels on for the y-axis
    50 ## only.
    51 ##
    52 ## @noindent
    53 ## The following options control the aspect ratio of the axes.
    54 ##
    55 ## @table @code
    56 ## @item "square"
    57 ## Force a square aspect ratio.
    58 ## @item "equal"
    59 ## Force x distance to equal y-distance.
    60 ## @item "normal"
    61 ## Restore the balance.
    62 ## @end table
    63 ##
    64 ## @noindent
    65 ## The following options control the way axis limits are interpreted.
    66 ##
    67 ## @table @code
    68 ## @item "auto" 
    69 ## Set the specified axes to have nice limits around the data
    70 ## or all if no axes are specified.
    71 ## @item "manual" 
    72 ## Fix the current axes limits.
    73 ## @item "tight"
    74 ## Fix axes to the limits of the data.
    75 ## @end table
    76 ##
    77 ## @noindent
    78 ## The option @code{"image"} is equivalent to @code{"tight"} and
    79 ## @code{"equal"}.
    80 ##
    81 ## @noindent
    82 ## The following options affect the appearance of tic marks.
    83 ##
    84 ## @table @code
    85 ## @item "on" 
    86 ## Turn tic marks and labels on for all axes.
    87 ## @item "off"
    88 ## Turn tic marks off for all axes.
    89 ## @item "tic[xyz]"
    90 ## Turn tic marks on for all axes, or turn them on for the
    91 ## specified axes and off for the remainder.
    92 ## @item "label[xyz]"
    93 ## Turn tic labels on for all axes, or turn them on for the 
    94 ## specified axes and off for the remainder.
    95 ## @item "nolabel"
    96 ## Turn tic labels off for all axes.
    97 ## @end table
    98 ## Note, if there are no tic marks for an axis, there can be no labels.
    99 ##
   100 ## @noindent
   101 ## The following options affect the direction of increasing values on
   102 ## the axes.
   103 ##
   104 ## @table @code
   105 ## @item "ij"
   106 ## Reverse y-axis, so lower values are nearer the top.
   107 ## @item "xy" 
   108 ## Restore y-axis, so higher values are nearer the top. 
   109 ## @end table
   110 ## 
   111 ## If an axes handle is passed as the first argument, then operate on
   112 ## this axes rather than the current axes.
   113 ## @end deftypefn
   114 
   115 ## Author: jwe
   116 
   117 function varargout = axis (varargin)
   118 
   119   [h, varargin, nargin] = __plt_get_axis_arg__ ("axis", varargin{:});
   120 
   121   oldh = gca ();
   122   unwind_protect
   123     axes (h);
   124     varargout = cell (max (nargin == 0, nargout), 1);
   125     if (isempty (varargout))
   126       __axis__ (h, varargin{:});
   127     else
   128       [varargout{:}] = __axis__ (h, varargin{:});
   129     endif
   130   unwind_protect_cleanup
   131     axes (oldh);
   132   end_unwind_protect
   133 
   134 endfunction
   135 
   136 function curr_axis = __axis__ (ca, ax, varargin)
   137 
   138   if (nargin == 1)
   139     if (nargout == 0)
   140       set (ca, "xlimmode", "auto", "ylimmode", "auto", "zlimmode", "auto");
   141     else
   142       xlim = get (ca, "xlim");
   143       ylim = get (ca, "ylim");
   144       zlim = get (ca, "zlim");
   145       curr_axis = [xlim, ylim, zlim];
   146     endif
   147 
   148   elseif (ischar (ax))
   149     len = length (ax);
   150 
   151     ## 'matrix mode' to reverse the y-axis
   152     if (strcmpi (ax, "ij"))
   153       set (ca, "ydir", "reverse");
   154     elseif (strcmpi (ax, "xy"))
   155       set (ca, "ydir", "normal");
   156 
   157       ## aspect ratio
   158     elseif (strcmpi (ax, "image"))
   159       __axis__ (ca, "equal")
   160       __do_tight_option__ (ca);
   161     elseif (strcmpi (ax, "square"))
   162       if (__gnuplot_has_feature__ ("screen_coordinates_for_{lrtb}margin"))
   163         set (ca, "dataaspectratio", [1, 1, 1]);
   164       else
   165         x = xlim;
   166         y = ylim;
   167         set (ca, "dataaspectratio", [(y(2)-y(1)), (x(2)-x(1)), 1]);
   168       endif
   169     elseif  (strcmp (ax, "equal"))
   170       if (__gnuplot_has_feature__ ("screen_coordinates_for_{lrtb}margin"))
   171         x = xlim;
   172         y = ylim;
   173         set (ca, "dataaspectratio", [(x(2)-x(1)), (y(2)-y(1)), 1]);
   174       else
   175         set (ca, "dataaspectratio", [1, 1, 1]);
   176       endif
   177     elseif (strcmpi (ax, "normal"))
   178       set (ca, "dataaspectratiomode", "auto");
   179 
   180       ## axis limits
   181     elseif (len >= 4 && strcmpi (ax(1:4), "auto"))
   182       if (len > 4)
   183 	if (any (ax == "x"))
   184 	  set (ca, "xlimmode", "auto");
   185 	endif
   186 	if (any (ax == "y"))
   187 	  set (ca, "ylimmode", "auto");
   188 	endif
   189 	if (any (ax == "z"))
   190 	  set (ca, "zlimmode", "auto");
   191 	endif
   192       else
   193 	set (ca, "xlimmode", "auto", "ylimmode", "auto", "zlimmode", "auto");
   194       endif
   195     elseif (strcmpi (ax, "manual"))
   196       ## fixes the axis limits, like axis(axis) should;
   197       set (ca, "xlimmode", "manual", "ylimmode", "manual", "zlimmode", "manual");
   198     elseif (strcmpi (ax, "tight"))
   199       ## sets the axis limits to the min and max of all data.
   200       __do_tight_option__ (ca);
   201       ## tic marks
   202     elseif (strcmpi (ax, "on") || strcmpi (ax, "tic"))
   203       set (ca, "xtickmode", "auto", "ytickmode", "auto", "ztickmode", "auto");
   204       if (strcmpi (ax, "on"))
   205         set (ca, "xticklabelmode", "auto", "yticklabelmode", "auto",
   206 	   "zticklabelmode", "auto");
   207       endif
   208       set (ca, "visible", "on");
   209     elseif (strcmpi (ax, "off"))
   210       set (ca, "xtick", [], "ytick", [], "ztick", []);
   211       set (ca, "visible", "off");
   212     elseif (len > 3 && strcmpi (ax(1:3), "tic"))
   213       if (any (ax == "x"))
   214 	set (ca, "xtickmode", "auto");
   215       else
   216 	set (ca, "xtick", []);
   217       endif
   218       if (any (ax == "y"))
   219 	set (ca, "ytickmode", "auto");
   220       else
   221 	set (ca, "ytick", []);
   222       endif
   223       if (any (ax == "z"))
   224 	set (ca, "ztickmode", "auto");
   225       else
   226 	set (ca, "ztick", []);
   227       endif
   228     elseif (strcmpi (ax, "label"))
   229       set (ca, "xticklabelmode", "auto", "yticklabelmode", "auto",
   230 	   "zticklabelmode", "auto");
   231     elseif (strcmpi (ax, "nolabel"))
   232       set (ca, "xticklabel", "", "yticklabel", "", "zticklabel", "");
   233     elseif (len > 5 && strcmpi (ax(1:5), "label"))
   234       if (any (ax == "x"))
   235 	set (ca, "xticklabelmode", "auto");
   236       else
   237 	set (ca, "xticklabel", "");
   238       endif
   239       if (any (ax == "y"))
   240 	set (ca, "yticklabelmode", "auto");
   241       else
   242 	set (ca, "yticklabel", "");
   243       endif
   244       if (any (ax == "z"))
   245 	set (ca, "zticklabelmode", "auto");
   246       else
   247 	set (ca, "zticklabel", "");
   248       endif
   249 
   250     else
   251       warning ("unknown axis option '%s'", ax);
   252     endif
   253 
   254   elseif (isvector (ax))
   255 
   256     len = length (ax);
   257 
   258     if (len != 2 && len != 4 && len != 6)
   259       error ("axis: expecting vector with 2, 4, or 6 elements");
   260     endif
   261 
   262     for i = 1:2:len
   263       if (ax(i) == ax(i+1))
   264 	error ("axis: limits(%d) cannot equal limits(%d)", i, i+1);
   265       endif
   266     endfor
   267 
   268     if (len > 1)
   269       set (ca, "xlim", [ax(1), ax(2)]);
   270     endif
   271 
   272     if (len > 3)
   273       set (ca, "ylim", [ax(3), ax(4)]);
   274     endif
   275 
   276     if (len > 5)
   277       set (ca, "zlim", [ax(5), ax(6)]);
   278     endif
   279 
   280   else
   281     error ("axis: expecting no args, or a vector with 2, 4, or 6 elements");
   282   endif
   283 
   284   if (! isempty (varargin))
   285     __axis__ (ca, varargin{:});
   286   endif
   287 
   288 endfunction
   289 
   290 function lims = __get_tight_lims__ (ca, ax)
   291 
   292   ## Get the limits for axis ("tight").
   293   ## AX should be one of "x", "y", or "z".
   294   kids = findobj (ca, "-property", strcat (ax, "data"));
   295   if (isempty (kids))
   296     ## Return the current limits.
   297     lims = get (ca, strcat (ax, "lim"));
   298   else
   299     data = get (kids, strcat (ax, "data"));
   300     if (iscell (data))
   301       lims(1) = min (cellfun (@min, data)(:));
   302       lims(2) = min (cellfun (@max, data)(:));
   303     else
   304       lims = [min(data(:)), max(data(:))];
   305     endif
   306   endif
   307 
   308 
   309 endfunction
   310 
   311 function __do_tight_option__ (ca)
   312 
   313   set (ca,
   314        "xlim", __get_tight_lims__ (ca, "x"),
   315        "ylim", __get_tight_lims__ (ca, "y"),
   316        "zlim", __get_tight_lims__ (ca, "z"));
   317 
   318 endfunction
   319 
   320 %!demo
   321 %! t=0:0.01:2*pi; x=sin(t);
   322 %!
   323 %! subplot(221);
   324 %! plot(t, x);
   325 %! title("normal plot");
   326 %!
   327 %! subplot(222);
   328 %! plot(t, x);
   329 %! title("square plot");
   330 %! axis("square");
   331 %!
   332 %! subplot(223);
   333 %! plot(t, x);
   334 %! title("equal plot");
   335 %! axis("equal");
   336 %! 
   337 %! subplot(224);
   338 %! plot(t, x);
   339 %! title("normal plot again");
   340 %! axis("normal");
   341 
   342 %!demo
   343 %! t=0:0.01:2*pi; x=sin(t);
   344 %!
   345 %! subplot(121);
   346 %! plot(t, x);
   347 %! title("ij plot");
   348 %! axis("ij");
   349 %!
   350 %! subplot(122);
   351 %! plot(t, x);
   352 %! title("xy plot");
   353 %! axis("xy");
   354 
   355 %!demo
   356 %! t=0:0.01:2*pi; x=sin(t);
   357 %!
   358 %! subplot(331);
   359 %! plot(t, x);
   360 %! title("x tics and labels");
   361 %! axis("ticx");
   362 %!
   363 %! subplot(332);
   364 %! plot(t, x);
   365 %! title("y tics and labels");
   366 %! axis("ticy");
   367 %!
   368 %! subplot(333);
   369 %! plot(t, x);
   370 %! title("axis off");
   371 %! axis("off");
   372 %!
   373 %! subplot(334);
   374 %! plot(t, x);
   375 %! title("x and y tics, x labels");
   376 %! axis("labelx","tic");
   377 %!
   378 %! subplot(335);
   379 %! plot(t, x);
   380 %! title("x and y tics, y labels");
   381 %! axis("labely","tic");
   382 %!
   383 %! subplot(336);
   384 %! plot(t, x);
   385 %! title("all tics but no labels");
   386 %! axis("nolabel","tic");
   387 %!
   388 %! subplot(337);
   389 %! plot(t, x);
   390 %! title("x tics, no labels");
   391 %! axis("nolabel","ticx");
   392 %!
   393 %! subplot(338);
   394 %! plot(t, x);
   395 %! title("y tics, no labels");
   396 %! axis("nolabel","ticy");
   397 %!
   398 %! subplot(339);
   399 %! plot(t, x);
   400 %! title("all tics and labels");
   401 %! axis("on");
   402 
   403 %!demo
   404 %! t=0:0.01:2*pi; x=sin(t);
   405 %!
   406 %! subplot(321);
   407 %! plot(t, x);
   408 %! title("axes at [0 3 0 1]")
   409 %! axis([0,3,0,1]);
   410 %!
   411 %! subplot(322);
   412 %! plot(t, x);
   413 %! title("auto");
   414 %! axis("auto");
   415 %!
   416 %! subplot(323);
   417 %! plot(t, x, ";sine [0:2pi];"); hold on;
   418 %! plot(-3:3,-3:3, ";line (-3,-3)->(3,3);"); hold off;
   419 %! title("manual");
   420 %! axis("manual");
   421 %!
   422 %! subplot(324);
   423 %! plot(t, x, ";sine [0:2pi];");
   424 %! title("axes at [0 3 0 1], then autox");
   425 %! axis([0,3,0,1]); axis("autox");
   426 %!
   427 %! subplot(325);
   428 %! plot(t, x, ";sine [0:2p];");
   429 %! axis([3,6,0,1]); axis("autoy");
   430 %! title("axes at [3 6 0 1], then autoy");
   431 %!
   432 %! subplot(326);
   433 %! plot(t, x);
   434 %! axis("tight");
   435 %! title("tight");
   436 
   437 %!demo
   438 %! clf
   439 %! axis image
   440 %! x=0:0.1:10;
   441 %! plot(x,sin(x))
   442 %! axis image
   443 %! title("image")
   444 
   445