1 ## Copyright (C) 1994-2012 John W. Eaton
3 ## This file is part of Octave.
5 ## Octave is free software; you can redistribute it and/or modify it
6 ## under the terms of the GNU General Public License as published by
7 ## the Free Software Foundation; either version 3 of the License, or (at
8 ## your option) any later version.
10 ## Octave is distributed in the hope that it will be useful, but
11 ## WITHOUT ANY WARRANTY; without even the implied warranty of
12 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 ## General Public License for more details.
15 ## You should have received a copy of the GNU General Public License
16 ## along with Octave; see the file COPYING. If not, see
17 ## <http://www.gnu.org/licenses/>.
20 ## @deftypefn {Function File} {} axis ()
21 ## @deftypefnx {Function File} {} axis ([@var{x}_lo @var{x}_hi])
22 ## @deftypefnx {Function File} {} axis ([@var{x}_lo @var{x}_hi @var{y}_lo @var{y}_hi])
23 ## @deftypefnx {Function File} {} axis ([@var{x}_lo @var{x}_hi @var{y}_lo @var{y}_hi @var{z}_lo @var{z}_hi])
24 ## @deftypefnx {Function File} {} axis (@var{option})
25 ## @deftypefnx {Function File} {} axis (@dots{}, @var{option})
26 ## @deftypefnx {Function File} {} axis (@var{h}, @dots{})
27 ## @deftypefnx {Function File} {@var{limits} =} axis ()
28 ## Set axis limits for plots.
30 ## The argument @var{limits} should be a 2-, 4-, or 6-element vector. The
31 ## first and second elements specify the lower and upper limits for the
32 ## x-axis. The third and fourth specify the limits for the y-axis, and the
33 ## fifth and sixth specify the limits for the z-axis.
35 ## Without any arguments, @code{axis} turns autoscaling on.
37 ## With one output argument, @code{x = axis} returns the current axes.
39 ## The vector argument specifying limits is optional, and additional
40 ## string arguments may be used to specify various axis properties. For
44 ## axis ([1, 2, 3, 4], "square");
48 ## forces a square aspect ratio, and
51 ## axis ("tic", "labely");
55 ## turns tic marks on for all axes and tic mark labels on for the y-axis
59 ## The following options control the aspect ratio of the axes.
63 ## Force a square aspect ratio.
66 ## Force x distance to equal y-distance.
69 ## Restore the balance.
73 ## The following options control the way axis limits are interpreted.
77 ## Set the specified axes to have nice limits around the data
78 ## or all if no axes are specified.
81 ## Fix the current axes limits.
84 ## Fix axes to the limits of the data.
88 ## The option @code{"image"} is equivalent to @code{"tight"} and
92 ## The following options affect the appearance of tic marks.
96 ## Turn tic marks and labels on for all axes.
99 ## Turn tic marks off for all axes.
102 ## Turn tic marks on for all axes, or turn them on for the
103 ## specified axes and off for the remainder.
105 ## @item "label[xyz]"
106 ## Turn tic labels on for all axes, or turn them on for the
107 ## specified axes and off for the remainder.
110 ## Turn tic labels off for all axes.
112 ## Note, if there are no tic marks for an axis, there can be no labels.
115 ## The following options affect the direction of increasing values on
120 ## Reverse y-axis, so lower values are nearer the top.
123 ## Restore y-axis, so higher values are nearer the top.
126 ## If an axes handle is passed as the first argument, then operate on
127 ## this axes rather than the current axes.
132 function varargout = axis (varargin)
134 [h, varargin, nargin] = __plt_get_axis_arg__ ("axis", varargin{:});
139 varargout = cell (max (nargin == 0, nargout), 1);
140 if (isempty (varargout))
141 __axis__ (h, varargin{:});
143 [varargout{:}] = __axis__ (h, varargin{:});
145 unwind_protect_cleanup
151 function curr_axis = __axis__ (ca, ax, varargin)
155 set (ca, "xlimmode", "auto", "ylimmode", "auto", "zlimmode", "auto");
157 xlim = get (ca, "xlim");
158 ylim = get (ca, "ylim");
159 view = get (ca, "view");
161 curr_axis = [xlim, ylim];
163 zlim = get (ca, "zlim");
164 curr_axis = [xlim, ylim, zlim];
171 ## 'matrix mode' to reverse the y-axis
172 if (strcmpi (ax, "ij"))
173 set (ca, "ydir", "reverse");
174 elseif (strcmpi (ax, "xy"))
175 set (ca, "ydir", "normal");
178 elseif (strcmpi (ax, "image"))
179 __axis__ (ca, "equal");
180 __do_tight_option__ (ca);
181 elseif (strcmpi (ax, "square"))
182 set (ca, "plotboxaspectratio", [1, 1, 1]);
183 elseif (strcmp (ax, "equal"))
184 if (strcmp (get (get (ca, "parent"), "__graphics_toolkit__"), "gnuplot"))
185 ## FIXME - gnuplot applies the aspect ratio activepostionproperty.
186 set (ca, "activepositionproperty", "position");
187 ## The following line is a trick used to trigger the recalculation of
188 ## aspect related magnitudes even if the aspect ratio is the same
189 ## (useful with the x11 gnuplot terminal after a window resize)
190 set (ca, "dataaspectratiomode", "auto");
192 set (ca, "dataaspectratio", [1, 1, 1]);
193 elseif (strcmpi (ax, "normal"))
194 set (ca, "plotboxaspectratio", [1, 1, 1]);
195 set (ca, "plotboxaspectratiomode", "auto");
198 elseif (len >= 4 && strcmpi (ax(1:4), "auto"))
201 set (ca, "xlimmode", "auto");
204 set (ca, "ylimmode", "auto");
207 set (ca, "zlimmode", "auto");
210 set (ca, "xlimmode", "auto", "ylimmode", "auto", "zlimmode", "auto");
212 elseif (strcmpi (ax, "manual"))
213 ## fixes the axis limits, like axis(axis) should;
214 set (ca, "xlimmode", "manual", "ylimmode", "manual", "zlimmode", "manual");
215 elseif (strcmpi (ax, "tight"))
216 ## sets the axis limits to the min and max of all data.
217 __do_tight_option__ (ca);
219 elseif (strcmpi (ax, "on") || strcmpi (ax, "tic"))
220 set (ca, "xtickmode", "auto", "ytickmode", "auto", "ztickmode", "auto");
221 if (strcmpi (ax, "on"))
222 set (ca, "xticklabelmode", "auto", "yticklabelmode", "auto",
223 "zticklabelmode", "auto");
225 set (ca, "visible", "on");
226 elseif (strcmpi (ax, "off"))
227 set (ca, "xtick", [], "ytick", [], "ztick", []);
228 set (ca, "visible", "off");
229 elseif (len > 3 && strcmpi (ax(1:3), "tic"))
231 set (ca, "xtickmode", "auto");
233 set (ca, "xtick", []);
236 set (ca, "ytickmode", "auto");
238 set (ca, "ytick", []);
241 set (ca, "ztickmode", "auto");
243 set (ca, "ztick", []);
245 elseif (strcmpi (ax, "label"))
246 set (ca, "xticklabelmode", "auto", "yticklabelmode", "auto",
247 "zticklabelmode", "auto");
248 elseif (strcmpi (ax, "nolabel"))
249 set (ca, "xticklabel", "", "yticklabel", "", "zticklabel", "");
250 elseif (len > 5 && strcmpi (ax(1:5), "label"))
252 set (ca, "xticklabelmode", "auto");
254 set (ca, "xticklabel", "");
257 set (ca, "yticklabelmode", "auto");
259 set (ca, "yticklabel", "");
262 set (ca, "zticklabelmode", "auto");
264 set (ca, "zticklabel", "");
268 warning ("unknown axis option '%s'", ax);
271 elseif (isvector (ax))
275 if (len != 2 && len != 4 && len != 6)
276 error ("axis: expecting vector with 2, 4, or 6 elements");
280 if (ax(i) >= ax(i+1))
281 error ("axis: limits(%d) must be less than limits(%d)", i, i+1);
286 set (ca, "xlim", [ax(1), ax(2)]);
290 set (ca, "ylim", [ax(3), ax(4)]);
294 set (ca, "zlim", [ax(5), ax(6)]);
298 error ("axis: expecting no args, or a vector with 2, 4, or 6 elements");
301 if (! isempty (varargin))
302 __axis__ (ca, varargin{:});
307 function lims = __get_tight_lims__ (ca, ax)
309 ## Get the limits for axis ("tight").
310 ## AX should be one of "x", "y", or "z".
311 kids = findobj (ca, "-property", strcat (ax, "data"));
312 ## The data properties for hggroups mirror their children.
313 ## Exclude the redundant hgroup values.
314 hg_kids = findobj (kids, "type", "hggroup");
315 kids = setdiff (kids, hg_kids);
317 ## Return the current limits.
318 lims = get (ca, strcat (ax, "lim"));
320 data = get (kids, strcat (ax, "data"));
321 scale = get (ca, strcat (ax, "scale"));
325 if (strcmp (scale, "log"))
327 data = cellfun (@(x) x(x>0), tmp, "uniformoutput", false);
328 n = cellfun (@isempty, data);
329 data(n) = cellfun (@(x) x(x<0), tmp(n), "uniformoutput", false);
331 data = cellfun (@(x) x(isfinite(x)), data, "uniformoutput", false);
332 data = data(! cellfun ("isempty", data));
333 if (! isempty (data))
334 lims_min = min (cellfun (@(x) min (x(:)), data(:)));
335 lims_max = max (cellfun (@(x) max (x(:)), data(:)));
336 lims = [lims_min, lims_max];
344 function __do_tight_option__ (ca)
347 "xlim", __get_tight_lims__ (ca, "x"),
348 "ylim", __get_tight_lims__ (ca, "y"));
349 if __calc_dimensions__ (ca) > 2
350 set (ca, "zlim", __get_tight_lims__ (ca, "z"));
357 %! t=0:0.01:2*pi; x=sin(t);
361 %! title("normal plot");
365 %! title("square plot");
370 %! title("equal plot");
375 %! title("normal plot again");
380 %! t=0:0.01:2*pi; x=sin(t);
394 %! t=0:0.01:2*pi; x=sin(t);
398 %! title("x tics and labels");
403 %! title("y tics and labels");
408 %! title("axis off");
413 %! title("x and y tics, x labels");
414 %! axis("labelx","tic");
418 %! title("x and y tics, y labels");
419 %! axis("labely","tic");
423 %! title("all tics but no labels");
424 %! axis("nolabel","tic");
428 %! title("x tics, no labels");
429 %! axis("nolabel","ticx");
433 %! title("y tics, no labels");
434 %! axis("nolabel","ticy");
438 %! title("all tics and labels");
443 %! t=0:0.01:2*pi; x=sin(t);
447 %! title("axes at [0 3 0 1]")
456 %! plot(t, x, ";sine [0:2pi];"); hold on;
457 %! plot(-3:3,-3:3, ";line (-3,-3)->(3,3);"); hold off;
462 %! plot(t, x, ";sine [0:2pi];");
463 %! title("axes at [0 3 0 1], then autox");
464 %! axis([0,3,0,1]); axis("autox");
467 %! plot(t, x, ";sine [0:2p];");
468 %! axis([3,6,0,1]); axis("autoy");
469 %! title("axes at [3 6 0 1], then autoy");
472 %! plot(t, sin(t), t, -2*sin(t/2))
486 %! [x,y,z] = peaks(50);
488 %! pcolor(x-x1,y-x1/2,z)
490 %! [x,y,z] = sombrero;
492 %! pcolor(s*x+x1,s*y+x1/2,5*z)
498 %! plot (x, x, x, -x)
499 %! set (gca, "yscale", "log")
500 %! legend ({"x >= 1", "x <= 1"}, "location", "north")
501 %! title ("ylim = [1, 10]")
505 %! loglog (1:20, "-s")
511 %! y = sin(x)./(1+abs(x)) + x*0.1 - .4;
513 %! title ("no plot box")
514 %! set (gca, "xaxislocation", "zero")
515 %! set (gca, "yaxislocation", "zero")
521 %! y = sin(x)./(1+abs(x)) + x*0.1 - .4;
523 %! title ("no plot box")
524 %! set (gca, "xaxislocation", "zero")
525 %! set (gca, "yaxislocation", "left")
531 %! y = sin(x)./(1+abs(x)) + x*0.1 - .4;
533 %! title ("no plot box")
534 %! set (gca, "xaxislocation", "zero")
535 %! set (gca, "yaxislocation", "right")
541 %! y = sin(x)./(1+abs(x)) + x*0.1 - .4;
543 %! title ("no plot box")
544 %! set (gca, "xaxislocation", "bottom")
545 %! set (gca, "yaxislocation", "zero")
551 %! y = sin(x)./(1+abs(x)) + x*0.1 - .4;
553 %! title ("no plot box")
554 %! set (gca, "xaxislocation", "top")
555 %! set (gca, "yaxislocation", "zero")
559 %! hf = figure ("visible", "off");
561 %! plot (11:20, [21:24, NaN, -Inf, 27:30]);
563 %! plot (11:20, 25.5 + rand (10));
565 %! assert (axis (), [11 20 21 30]);
566 %! unwind_protect_cleanup
568 %! end_unwind_protect
571 %! hf = figure ("visible", "off");
573 %! a = logspace (-5, 1, 10);
576 %! assert (axis (), [1e-5, 10, -10, -1e-5])
577 %! unwind_protect_cleanup
579 %! end_unwind_protect