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