axis.m: Fix bug for 'axis tight' with multiple lines, modify demo.
1 ## Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2002, 2003, 2004,
2 ## 2005, 2006, 2007, 2008, 2009 John W. Eaton
4 ## This file is part of Octave.
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.
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.
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/>.
21 ## @deftypefn {Function File} {} axis (@var{limits})
22 ## Set axis limits for plots.
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.
29 ## Without any arguments, @code{axis} turns autoscaling on.
31 ## With one output argument, @code{x = axis} returns the current axes
33 ## The vector argument specifying limits is optional, and additional
34 ## string arguments may be used to specify various axis properties. For
38 ## axis ([1, 2, 3, 4], "square");
42 ## forces a square aspect ratio, and
45 ## axis ("labely", "tic");
49 ## turns tic marks on for all axes and tic mark labels on for the y-axis
53 ## The following options control the aspect ratio of the axes.
57 ## Force a square aspect ratio.
59 ## Force x distance to equal y-distance.
61 ## Restore the balance.
65 ## The following options control the way axis limits are interpreted.
69 ## Set the specified axes to have nice limits around the data
70 ## or all if no axes are specified.
72 ## Fix the current axes limits.
74 ## Fix axes to the limits of the data.
78 ## The option @code{"image"} is equivalent to @code{"tight"} and
82 ## The following options affect the appearance of tic marks.
86 ## Turn tic marks and labels on for all axes.
88 ## Turn tic marks off for all axes.
90 ## Turn tic marks on for all axes, or turn them on for the
91 ## specified axes and off for the remainder.
93 ## Turn tic labels on for all axes, or turn them on for the
94 ## specified axes and off for the remainder.
96 ## Turn tic labels off for all axes.
98 ## Note, if there are no tic marks for an axis, there can be no labels.
101 ## The following options affect the direction of increasing values on
106 ## Reverse y-axis, so lower values are nearer the top.
108 ## Restore y-axis, so higher values are nearer the top.
111 ## If an axes handle is passed as the first argument, then operate on
112 ## this axes rather than the current axes.
117 function varargout = axis (varargin)
119 [h, varargin, nargin] = __plt_get_axis_arg__ ("axis", varargin{:});
124 varargout = cell (max (nargin == 0, nargout), 1);
125 if (isempty (varargout))
126 __axis__ (h, varargin{:});
128 [varargout{:}] = __axis__ (h, varargin{:});
130 unwind_protect_cleanup
136 function curr_axis = __axis__ (ca, ax, varargin)
140 set (ca, "xlimmode", "auto", "ylimmode", "auto", "zlimmode", "auto");
142 xlim = get (ca, "xlim");
143 ylim = get (ca, "ylim");
144 zlim = get (ca, "zlim");
145 curr_axis = [xlim, ylim, zlim];
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");
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]);
167 set (ca, "dataaspectratio", [(y(2)-y(1)), (x(2)-x(1)), 1]);
169 elseif (strcmp (ax, "equal"))
170 if (__gnuplot_has_feature__ ("screen_coordinates_for_{lrtb}margin"))
173 set (ca, "dataaspectratio", [(x(2)-x(1)), (y(2)-y(1)), 1]);
175 set (ca, "dataaspectratio", [1, 1, 1]);
177 elseif (strcmpi (ax, "normal"))
178 set (ca, "dataaspectratiomode", "auto");
181 elseif (len >= 4 && strcmpi (ax(1:4), "auto"))
184 set (ca, "xlimmode", "auto");
187 set (ca, "ylimmode", "auto");
190 set (ca, "zlimmode", "auto");
193 set (ca, "xlimmode", "auto", "ylimmode", "auto", "zlimmode", "auto");
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);
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");
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"))
214 set (ca, "xtickmode", "auto");
216 set (ca, "xtick", []);
219 set (ca, "ytickmode", "auto");
221 set (ca, "ytick", []);
224 set (ca, "ztickmode", "auto");
226 set (ca, "ztick", []);
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"))
235 set (ca, "xticklabelmode", "auto");
237 set (ca, "xticklabel", "");
240 set (ca, "yticklabelmode", "auto");
242 set (ca, "yticklabel", "");
245 set (ca, "zticklabelmode", "auto");
247 set (ca, "zticklabel", "");
251 warning ("unknown axis option '%s'", ax);
254 elseif (isvector (ax))
258 if (len != 2 && len != 4 && len != 6)
259 error ("axis: expecting vector with 2, 4, or 6 elements");
263 if (ax(i) == ax(i+1))
264 error ("axis: limits(%d) cannot equal limits(%d)", i, i+1);
269 set (ca, "xlim", [ax(1), ax(2)]);
273 set (ca, "ylim", [ax(3), ax(4)]);
277 set (ca, "zlim", [ax(5), ax(6)]);
281 error ("axis: expecting no args, or a vector with 2, 4, or 6 elements");
284 if (! isempty (varargin))
285 __axis__ (ca, varargin{:});
290 function lims = __get_tight_lims__ (ca, ax)
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"));
296 ## Return the current limits.
297 lims = get (ca, strcat (ax, "lim"));
299 data = get (kids, strcat (ax, "data"));
301 data = data (find (! cellfun (@isempty, data)));
302 if (! isempty (data))
303 lims(1) = min (cellfun (@min, data)(:));
304 lims(2) = max (cellfun (@max, data)(:));
309 lims = [min(data(:)), max(data(:))];
314 function __do_tight_option__ (ca)
317 "xlim", __get_tight_lims__ (ca, "x"),
318 "ylim", __get_tight_lims__ (ca, "y"),
319 "zlim", __get_tight_lims__ (ca, "z"));
324 %! t=0:0.01:2*pi; x=sin(t);
328 %! title("normal plot");
332 %! title("square plot");
337 %! title("equal plot");
342 %! title("normal plot again");
346 %! t=0:0.01:2*pi; x=sin(t);
359 %! t=0:0.01:2*pi; x=sin(t);
363 %! title("x tics and labels");
368 %! title("y tics and labels");
373 %! title("axis off");
378 %! title("x and y tics, x labels");
379 %! axis("labelx","tic");
383 %! title("x and y tics, y labels");
384 %! axis("labely","tic");
388 %! title("all tics but no labels");
389 %! axis("nolabel","tic");
393 %! title("x tics, no labels");
394 %! axis("nolabel","ticx");
398 %! title("y tics, no labels");
399 %! axis("nolabel","ticy");
403 %! title("all tics and labels");
407 %! t=0:0.01:2*pi; x=sin(t);
411 %! title("axes at [0 3 0 1]")
420 %! plot(t, x, ";sine [0:2pi];"); hold on;
421 %! plot(-3:3,-3:3, ";line (-3,-3)->(3,3);"); hold off;
426 %! plot(t, x, ";sine [0:2pi];");
427 %! title("axes at [0 3 0 1], then autox");
428 %! axis([0,3,0,1]); axis("autox");
431 %! plot(t, x, ";sine [0:2p];");
432 %! axis([3,6,0,1]); axis("autoy");
433 %! title("axes at [3 6 0 1], then autoy");
436 %! plot(t, sin(t), t, -2*sin(t/2))