]> Creatis software - CreaPhase.git/blob - octave_packages/m/plot/axis.m
update packages
[CreaPhase.git] / octave_packages / m / plot / axis.m
1 ## Copyright (C) 1994-2012 John W. Eaton
2 ##
3 ## This file is part of Octave.
4 ##
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.
9 ##
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.
14 ##
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/>.
18
19 ## -*- texinfo -*-
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.
29 ##
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.
34 ##
35 ## Without any arguments, @code{axis} turns autoscaling on.
36 ##
37 ## With one output argument, @code{x = axis} returns the current axes.
38 ##
39 ## The vector argument specifying limits is optional, and additional
40 ## string arguments may be used to specify various axis properties.  For
41 ## example,
42 ##
43 ## @example
44 ## axis ([1, 2, 3, 4], "square");
45 ## @end example
46 ##
47 ## @noindent
48 ## forces a square aspect ratio, and
49 ##
50 ## @example
51 ## axis ("tic", "labely");
52 ## @end example
53 ##
54 ## @noindent
55 ## turns tic marks on for all axes and tic mark labels on for the y-axis
56 ## only.
57 ##
58 ## @noindent
59 ## The following options control the aspect ratio of the axes.
60 ##
61 ## @table @asis
62 ## @item "square"
63 ## Force a square aspect ratio.
64 ##
65 ## @item "equal"
66 ## Force x distance to equal y-distance.
67 ##
68 ## @item "normal"
69 ## Restore the balance.
70 ## @end table
71 ##
72 ## @noindent
73 ## The following options control the way axis limits are interpreted.
74 ##
75 ## @table @asis
76 ## @item "auto"
77 ## Set the specified axes to have nice limits around the data
78 ## or all if no axes are specified.
79 ##
80 ## @item "manual"
81 ## Fix the current axes limits.
82 ##
83 ## @item "tight"
84 ## Fix axes to the limits of the data.
85 ## @end table
86 ##
87 ## @noindent
88 ## The option @code{"image"} is equivalent to @code{"tight"} and
89 ## @code{"equal"}.
90 ##
91 ## @noindent
92 ## The following options affect the appearance of tic marks.
93 ##
94 ## @table @asis
95 ## @item "on"
96 ## Turn tic marks and labels on for all axes.
97 ##
98 ## @item "off"
99 ## Turn tic marks off for all axes.
100 ##
101 ## @item "tic[xyz]"
102 ## Turn tic marks on for all axes, or turn them on for the
103 ## specified axes and off for the remainder.
104 ##
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.
108 ##
109 ## @item "nolabel"
110 ## Turn tic labels off for all axes.
111 ## @end table
112 ## Note, if there are no tic marks for an axis, there can be no labels.
113 ##
114 ## @noindent
115 ## The following options affect the direction of increasing values on
116 ## the axes.
117 ##
118 ## @table @asis
119 ## @item "ij"
120 ## Reverse y-axis, so lower values are nearer the top.
121 ##
122 ## @item "xy"
123 ## Restore y-axis, so higher values are nearer the top.
124 ## @end table
125 ##
126 ## If an axes handle is passed as the first argument, then operate on
127 ## this axes rather than the current axes.
128 ## @end deftypefn
129
130 ## Author: jwe
131
132 function varargout = axis (varargin)
133
134   [h, varargin, nargin] = __plt_get_axis_arg__ ("axis", varargin{:});
135
136   oldh = gca ();
137   unwind_protect
138     axes (h);
139     varargout = cell (max (nargin == 0, nargout), 1);
140     if (isempty (varargout))
141       __axis__ (h, varargin{:});
142     else
143       [varargout{:}] = __axis__ (h, varargin{:});
144     endif
145   unwind_protect_cleanup
146     axes (oldh);
147   end_unwind_protect
148
149 endfunction
150
151 function curr_axis = __axis__ (ca, ax, varargin)
152
153   if (nargin == 1)
154     if (nargout == 0)
155       set (ca, "xlimmode", "auto", "ylimmode", "auto", "zlimmode", "auto");
156     else
157       xlim = get (ca, "xlim");
158       ylim = get (ca, "ylim");
159       view = get (ca, "view");
160       if (view(2) == 90)
161         curr_axis = [xlim, ylim];
162       else
163         zlim = get (ca, "zlim");
164         curr_axis = [xlim, ylim, zlim];
165       endif
166     endif
167
168   elseif (ischar (ax))
169     len = length (ax);
170
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");
176
177       ## aspect ratio
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");
191       endif
192       set (ca, "dataaspectratio", [1, 1, 1]);
193     elseif (strcmpi (ax, "normal"))
194       set (ca, "plotboxaspectratio", [1, 1, 1]);
195       set (ca, "plotboxaspectratiomode", "auto");
196
197       ## axis limits
198     elseif (len >= 4 && strcmpi (ax(1:4), "auto"))
199       if (len > 4)
200         if (any (ax == "x"))
201           set (ca, "xlimmode", "auto");
202         endif
203         if (any (ax == "y"))
204           set (ca, "ylimmode", "auto");
205         endif
206         if (any (ax == "z"))
207           set (ca, "zlimmode", "auto");
208         endif
209       else
210         set (ca, "xlimmode", "auto", "ylimmode", "auto", "zlimmode", "auto");
211       endif
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);
218       ## tic marks
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");
224       endif
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"))
230       if (any (ax == "x"))
231         set (ca, "xtickmode", "auto");
232       else
233         set (ca, "xtick", []);
234       endif
235       if (any (ax == "y"))
236         set (ca, "ytickmode", "auto");
237       else
238         set (ca, "ytick", []);
239       endif
240       if (any (ax == "z"))
241         set (ca, "ztickmode", "auto");
242       else
243         set (ca, "ztick", []);
244       endif
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"))
251       if (any (ax == "x"))
252         set (ca, "xticklabelmode", "auto");
253       else
254         set (ca, "xticklabel", "");
255       endif
256       if (any (ax == "y"))
257         set (ca, "yticklabelmode", "auto");
258       else
259         set (ca, "yticklabel", "");
260       endif
261       if (any (ax == "z"))
262         set (ca, "zticklabelmode", "auto");
263       else
264         set (ca, "zticklabel", "");
265       endif
266
267     else
268       warning ("unknown axis option '%s'", ax);
269     endif
270
271   elseif (isvector (ax))
272
273     len = length (ax);
274
275     if (len != 2 && len != 4 && len != 6)
276       error ("axis: expecting vector with 2, 4, or 6 elements");
277     endif
278
279     for i = 1:2:len
280       if (ax(i) >= ax(i+1))
281         error ("axis: limits(%d) must be less than limits(%d)", i, i+1);
282       endif
283     endfor
284
285     if (len > 1)
286       set (ca, "xlim", [ax(1), ax(2)]);
287     endif
288
289     if (len > 3)
290       set (ca, "ylim", [ax(3), ax(4)]);
291     endif
292
293     if (len > 5)
294       set (ca, "zlim", [ax(5), ax(6)]);
295     endif
296
297   else
298     error ("axis: expecting no args, or a vector with 2, 4, or 6 elements");
299   endif
300
301   if (! isempty (varargin))
302     __axis__ (ca, varargin{:});
303   endif
304
305 endfunction
306
307 function lims = __get_tight_lims__ (ca, ax)
308
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);
316   if (isempty (kids))
317     ## Return the current limits.
318     lims = get (ca, strcat (ax, "lim"));
319   else
320     data = get (kids, strcat (ax, "data"));
321     scale = get (ca, strcat (ax, "scale"));
322     if (! iscell (data))
323       data = {data};
324     end
325     if (strcmp (scale, "log"))
326       tmp = data;
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);
330     endif
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];
337     else
338       lims = [0, 1];
339     endif
340   endif
341
342 endfunction
343
344 function __do_tight_option__ (ca)
345
346   set (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"));
351   endif
352
353 endfunction
354
355 %!demo
356 %! clf
357 %! t=0:0.01:2*pi; x=sin(t);
358 %!
359 %! subplot(221);
360 %! plot(t, x);
361 %! title("normal plot");
362 %!
363 %! subplot(222);
364 %! plot(t, x);
365 %! title("square plot");
366 %! axis("square");
367 %!
368 %! subplot(223);
369 %! plot(t, x);
370 %! title("equal plot");
371 %! axis("equal");
372 %!
373 %! subplot(224);
374 %! plot(t, x);
375 %! title("normal plot again");
376 %! axis("normal");
377
378 %!demo
379 %! clf
380 %! t=0:0.01:2*pi; x=sin(t);
381 %!
382 %! subplot(121);
383 %! plot(t, x);
384 %! title("ij plot");
385 %! axis("ij");
386 %!
387 %! subplot(122);
388 %! plot(t, x);
389 %! title("xy plot");
390 %! axis("xy");
391
392 %!demo
393 %! clf
394 %! t=0:0.01:2*pi; x=sin(t);
395 %!
396 %! subplot(331);
397 %! plot(t, x);
398 %! title("x tics and labels");
399 %! axis("ticx");
400 %!
401 %! subplot(332);
402 %! plot(t, x);
403 %! title("y tics and labels");
404 %! axis("ticy");
405 %!
406 %! subplot(333);
407 %! plot(t, x);
408 %! title("axis off");
409 %! axis("off");
410 %!
411 %! subplot(334);
412 %! plot(t, x);
413 %! title("x and y tics, x labels");
414 %! axis("labelx","tic");
415 %!
416 %! subplot(335);
417 %! plot(t, x);
418 %! title("x and y tics, y labels");
419 %! axis("labely","tic");
420 %!
421 %! subplot(336);
422 %! plot(t, x);
423 %! title("all tics but no labels");
424 %! axis("nolabel","tic");
425 %!
426 %! subplot(337);
427 %! plot(t, x);
428 %! title("x tics, no labels");
429 %! axis("nolabel","ticx");
430 %!
431 %! subplot(338);
432 %! plot(t, x);
433 %! title("y tics, no labels");
434 %! axis("nolabel","ticy");
435 %!
436 %! subplot(339);
437 %! plot(t, x);
438 %! title("all tics and labels");
439 %! axis("on");
440
441 %!demo
442 %! clf
443 %! t=0:0.01:2*pi; x=sin(t);
444 %!
445 %! subplot(321);
446 %! plot(t, x);
447 %! title("axes at [0 3 0 1]")
448 %! axis([0,3,0,1]);
449 %!
450 %! subplot(322);
451 %! plot(t, x);
452 %! title("auto");
453 %! axis("auto");
454 %!
455 %! subplot(323);
456 %! plot(t, x, ";sine [0:2pi];"); hold on;
457 %! plot(-3:3,-3:3, ";line (-3,-3)->(3,3);"); hold off;
458 %! title("manual");
459 %! axis("manual");
460 %!
461 %! subplot(324);
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");
465 %!
466 %! subplot(325);
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");
470 %!
471 %! subplot(326);
472 %! plot(t, sin(t), t, -2*sin(t/2))
473 %! axis("tight");
474 %! title("tight");
475
476 %!demo
477 %! clf
478 %! axis image
479 %! x=0:0.1:10;
480 %! plot(x,sin(x))
481 %! axis image
482 %! title("image")
483
484 %!demo
485 %! clf
486 %! [x,y,z] = peaks(50);
487 %! x1 = max(x(:));
488 %! pcolor(x-x1,y-x1/2,z)
489 %! hold on
490 %! [x,y,z] = sombrero;
491 %! s = x1/max(x(:));
492 %! pcolor(s*x+x1,s*y+x1/2,5*z)
493 %! axis tight
494
495 %!demo
496 %! clf
497 %! x = -10:10;
498 %! plot (x, x, x, -x)
499 %! set (gca, "yscale", "log")
500 %! legend ({"x >= 1", "x <= 1"}, "location", "north")
501 %! title ("ylim = [1, 10]")
502
503 %!demo
504 %! clf
505 %! loglog (1:20, "-s")
506 %! axis tight
507
508 %!demo
509 %! clf
510 %! x = -10:0.1:10;
511 %! y = sin(x)./(1+abs(x)) + x*0.1 - .4;
512 %! plot (x, y)
513 %! title ("no plot box")
514 %! set (gca, "xaxislocation", "zero")
515 %! set (gca, "yaxislocation", "zero")
516 %! box off
517
518 %!demo
519 %! clf
520 %! x = -10:0.1:10;
521 %! y = sin(x)./(1+abs(x)) + x*0.1 - .4;
522 %! plot (x, y)
523 %! title ("no plot box")
524 %! set (gca, "xaxislocation", "zero")
525 %! set (gca, "yaxislocation", "left")
526 %! box off
527
528 %!demo
529 %! clf
530 %! x = -10:0.1:10;
531 %! y = sin(x)./(1+abs(x)) + x*0.1 - .4;
532 %! plot (x, y)
533 %! title ("no plot box")
534 %! set (gca, "xaxislocation", "zero")
535 %! set (gca, "yaxislocation", "right")
536 %! box off
537
538 %!demo
539 %! clf
540 %! x = -10:0.1:10;
541 %! y = sin(x)./(1+abs(x)) + x*0.1 - .4;
542 %! plot (x, y)
543 %! title ("no plot box")
544 %! set (gca, "xaxislocation", "bottom")
545 %! set (gca, "yaxislocation", "zero")
546 %! box off
547
548 %!demo
549 %! clf
550 %! x = -10:0.1:10;
551 %! y = sin(x)./(1+abs(x)) + x*0.1 - .4;
552 %! plot (x, y)
553 %! title ("no plot box")
554 %! set (gca, "xaxislocation", "top")
555 %! set (gca, "yaxislocation", "zero")
556 %! box off
557
558 %!test
559 %! hf = figure ("visible", "off");
560 %! unwind_protect
561 %!   plot (11:20, [21:24, NaN, -Inf, 27:30]);
562 %!   hold all;
563 %!   plot (11:20, 25.5 + rand (10));
564 %!   axis tight;
565 %!   assert (axis (), [11 20 21 30]);
566 %! unwind_protect_cleanup
567 %!   close (hf);
568 %! end_unwind_protect
569
570 %!test
571 %! hf = figure ("visible", "off");
572 %! unwind_protect
573 %!   a = logspace (-5, 1, 10);
574 %!   loglog (a, -a)
575 %!   axis tight;
576 %!   assert (axis (), [1e-5, 10, -10, -1e-5])
577 %! unwind_protect_cleanup
578 %!   close (hf);
579 %! end_unwind_protect
580