Mercurial > hg > octave-nkf
annotate scripts/plot/axis.m @ 7994:8ccd9b0bf6bc
plot/axis.m (__get_tight_lims__): don't fail if data is not a vector
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Tue, 29 Jul 2008 15:34:13 -0400 |
parents | b052b844e094 |
children | 73d6b71788c0 |
rev | line source |
---|---|
7017 | 1 ## Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2002, 2003, 2004, |
2 ## 2005, 2006, 2007 John W. Eaton | |
2313 | 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 | |
7016 | 8 ## the Free Software Foundation; either version 3 of the License, or (at |
9 ## your option) any later version. | |
2313 | 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 | |
7016 | 17 ## along with Octave; see the file COPYING. If not, see |
18 ## <http://www.gnu.org/licenses/>. | |
590 | 19 |
3368 | 20 ## -*- texinfo -*- |
21 ## @deftypefn {Function File} {} axis (@var{limits}) | |
3667 | 22 ## Set axis limits for plots. |
3426 | 23 ## |
3368 | 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. | |
3426 | 28 ## |
4945 | 29 ## Without any arguments, @code{axis} turns autoscaling on. |
30 ## | |
31 ## With one output argument, @code{x=axis} returns the current axes | |
3667 | 32 ## |
3668 | 33 ## The vector argument specifying limits is optional, and additional |
34 ## string arguments may be used to specify various axis properties. For | |
3667 | 35 ## example, |
36 ## | |
37 ## @example | |
38 ## axis ([1, 2, 3, 4], "square"); | |
39 ## @end example | |
40 ## | |
41 ## @noindent | |
3668 | 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. | |
3667 | 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 (not implemented). | |
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]" | |
3668 | 90 ## Turn tic marks on for all axes, or turn them on for the |
91 ## specified axes and off for the remainder. | |
3667 | 92 ## @item "label[xyz]" |
3668 | 93 ## Turn tic labels on for all axes, or turn them on for the |
94 ## specified axes and off for the remainder. | |
3667 | 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 | |
4945 | 110 ## |
7189 | 111 ## If an axes handle is passed as the first argument, then operate on |
112 ## this axes rather than the current axes. | |
3368 | 113 ## @end deftypefn |
590 | 114 |
2314 | 115 ## Author: jwe |
116 | |
5561 | 117 ## PKG_ADD: mark_as_command axis |
5560 | 118 |
7189 | 119 function varargout = axis (varargin) |
590 | 120 |
7215 | 121 [h, varargin, nargin] = __plt_get_axis_arg__ ("axis", varargin{:}); |
7216 | 122 |
7215 | 123 oldh = gca (); |
124 unwind_protect | |
125 axes (h); | |
7189 | 126 varargout = cell (max (nargin == 0, nargout), 1); |
127 if (isempty (varargout)) | |
7215 | 128 __axis__ (h, varargin{:}); |
7189 | 129 else |
7215 | 130 [varargout{:}] = __axis__ (h, varargin{:}); |
7189 | 131 endif |
7215 | 132 unwind_protect_cleanup |
133 axes (oldh); | |
134 end_unwind_protect | |
590 | 135 |
7189 | 136 endfunction |
137 | |
138 function curr_axis = __axis__ (ca, ax, varargin) | |
139 | |
140 if (nargin == 1) | |
4945 | 141 if (nargout == 0) |
6257 | 142 set (ca, "xlimmode", "auto", "ylimmode", "auto", "zlimmode", "auto"); |
4945 | 143 else |
6257 | 144 xlim = get (ca, "xlim"); |
145 ylim = get (ca, "ylim"); | |
146 zlim = get (ca, "zlim"); | |
147 curr_axis = [xlim, ylim, zlim]; | |
4945 | 148 endif |
3667 | 149 |
5443 | 150 elseif (ischar (ax)) |
3667 | 151 ax = tolower (ax); |
4340 | 152 len = length (ax); |
3667 | 153 |
154 ## 'matrix mode' to reverse the y-axis | |
155 if (strcmp (ax, "ij")) | |
6257 | 156 set (ca, "ydir", "reverse"); |
3667 | 157 elseif (strcmp (ax, "xy")) |
6257 | 158 set (ca, "ydir", "normal"); |
3667 | 159 |
160 ## aspect ratio | |
161 elseif (strcmp (ax, "image")) | |
6257 | 162 set (ca, "dataaspectratio", [1, 1, 1]); |
7376 | 163 __do_tight_option__ (ca); |
6257 | 164 elseif (strcmp (ax, "equal") || strcmp (ax, "square")) |
165 set (ca, "dataaspectratio", [1, 1, 1]); | |
3667 | 166 elseif (strcmp (ax, "normal")) |
6257 | 167 set (ca, "dataaspectratiomode", "auto"); |
3667 | 168 |
169 ## axis limits | |
4340 | 170 elseif (len >= 4 && strcmp (ax(1:4), "auto")) |
171 if (len > 4) | |
6257 | 172 if (any (ax == "x")) |
173 set (ca, "xlimmode", "auto"); | |
174 endif | |
175 if (any (ax == "y")) | |
176 set (ca, "ylimmode", "auto"); | |
177 endif | |
178 if (any (ax == "z")) | |
179 set (ca, "zlimmode", "auto"); | |
180 endif | |
3667 | 181 else |
6257 | 182 set (ca, "xlimmode", "auto", "ylimmode", "auto", "zlimmode", "auto"); |
3667 | 183 endif |
184 elseif (strcmp (ax, "manual")) | |
185 ## fixes the axis limits, like axis(axis) should; | |
6257 | 186 set (ca, "xlimmode", "manual", "ylimmode", "manual", "zlimmode", "manual"); |
3667 | 187 elseif (strcmp (ax, "tight")) |
7376 | 188 ## sets the axis limits to the min and max of all data. |
189 __do_tight_option__ (ca); | |
3667 | 190 |
191 ## tic marks | |
6257 | 192 elseif (strcmp (ax, "on") || strcmp (ax, "tic")) |
193 set (ca, "xtickmode", "auto", "ytickmode", "auto", "ztickmode", "auto"); | |
194 set (ca, "xticklabelmode", "auto", "yticklabelmode", "auto", | |
195 "zticklabelmode", "auto"); | |
6765 | 196 set (ca, "visible", "on"); |
3667 | 197 elseif (strcmp (ax, "off")) |
6257 | 198 set (ca, "xtick", [], "ytick", [], "ztick", []); |
6765 | 199 set (ca, "visible", "off"); |
4340 | 200 elseif (len > 3 && strcmp (ax(1:3), "tic")) |
201 if (any (ax == "x")) | |
6257 | 202 set (ca, "xtickmode", "auto"); |
3667 | 203 else |
6257 | 204 set (ca, "xtick", []); |
3667 | 205 endif |
4340 | 206 if (any (ax == "y")) |
6257 | 207 set (ca, "ytickmode", "auto"); |
3667 | 208 else |
6257 | 209 set (ca, "ytick", []); |
3667 | 210 endif |
4340 | 211 if (any (ax == "z")) |
6257 | 212 set (ca, "ztickmode", "auto"); |
3667 | 213 else |
6257 | 214 set (ca, "ztick", []); |
3667 | 215 endif |
216 elseif (strcmp (ax, "label")) | |
6257 | 217 set (ca, "xticklabelmode", "auto", "yticklabelmode", "auto", |
218 "zticklabelmode", "auto"); | |
3667 | 219 elseif (strcmp (ax, "nolabel")) |
6257 | 220 set (ca, "xticklabel", "", "yticklabel", "", "zticklabel", ""); |
4340 | 221 elseif (len > 5 && strcmp (ax(1:5), "label")) |
222 if (any (ax == "x")) | |
6257 | 223 set (ca, "xticklabelmode", "auto"); |
3667 | 224 else |
6257 | 225 set (ca, "xticklabel", ""); |
3667 | 226 endif |
4340 | 227 if (any (ax == "y")) |
6257 | 228 set (ca, "yticklabelmode", "auto"); |
3667 | 229 else |
6257 | 230 set (ca, "yticklabel", ""); |
3667 | 231 endif |
4340 | 232 if (any (ax == "z")) |
6257 | 233 set (ca, "zticklabelmode", "auto"); |
3667 | 234 else |
6257 | 235 set (ca, "zticklabel", ""); |
3667 | 236 endif |
237 | |
238 else | |
4259 | 239 warning ("unknown axis option '%s'", ax); |
3667 | 240 endif |
241 | |
4030 | 242 elseif (isvector (ax)) |
590 | 243 |
244 len = length (ax); | |
245 | |
246 if (len != 2 && len != 4 && len != 6) | |
247 error ("axis: expecting vector with 2, 4, or 6 elements"); | |
248 endif | |
249 | |
5627 | 250 for i = 1:2:len |
251 if (ax(i) == ax(i+1)) | |
252 error ("axis: limits(%d) cannot equal limits(%d)", i, i+1); | |
253 endif | |
254 endfor | |
255 | |
590 | 256 if (len > 1) |
6257 | 257 set (ca, "xlim", [ax(1), ax(2)]); |
590 | 258 endif |
259 | |
260 if (len > 3) | |
6257 | 261 set (ca, "ylim", [ax(3), ax(4)]); |
590 | 262 endif |
263 | |
264 if (len > 5) | |
6257 | 265 set (ca, "zlim", [ax(5), ax(6)]); |
590 | 266 endif |
267 | |
268 else | |
595 | 269 error ("axis: expecting no args, or a vector with 2, 4, or 6 elements"); |
590 | 270 endif |
271 | |
7376 | 272 if (! isempty (varargin)) |
7189 | 273 __axis__ (ca, varargin{:}); |
3667 | 274 endif |
6447 | 275 |
590 | 276 endfunction |
3667 | 277 |
7376 | 278 function lims = __get_tight_lims__ (ca, ax) |
279 | |
280 ## Get the limits for axis ("tight"). | |
281 ## AX should be one of "x", "y", or "z". | |
7994
8ccd9b0bf6bc
plot/axis.m (__get_tight_lims__): don't fail if data is not a vector
John W. Eaton <jwe@octave.org>
parents:
7376
diff
changeset
|
282 kids = findobj (ca, "-property", strcat (ax, "data")); |
7376 | 283 if (isempty (kids)) |
284 ## Return the current limits. | |
7994
8ccd9b0bf6bc
plot/axis.m (__get_tight_lims__): don't fail if data is not a vector
John W. Eaton <jwe@octave.org>
parents:
7376
diff
changeset
|
285 lims = get (ca, strcat (ax, "lim")); |
7376 | 286 else |
7994
8ccd9b0bf6bc
plot/axis.m (__get_tight_lims__): don't fail if data is not a vector
John W. Eaton <jwe@octave.org>
parents:
7376
diff
changeset
|
287 data = get (kids, strcat (ax, "data")); |
7376 | 288 if (iscell (data)) |
7994
8ccd9b0bf6bc
plot/axis.m (__get_tight_lims__): don't fail if data is not a vector
John W. Eaton <jwe@octave.org>
parents:
7376
diff
changeset
|
289 lims(1) = min (cellfun (@min, data)(:)); |
8ccd9b0bf6bc
plot/axis.m (__get_tight_lims__): don't fail if data is not a vector
John W. Eaton <jwe@octave.org>
parents:
7376
diff
changeset
|
290 lims(2) = min (cellfun (@max, data)(:)); |
7376 | 291 else |
7994
8ccd9b0bf6bc
plot/axis.m (__get_tight_lims__): don't fail if data is not a vector
John W. Eaton <jwe@octave.org>
parents:
7376
diff
changeset
|
292 lims = [min(data(:)), max(data(:))]; |
7376 | 293 end |
294 end | |
295 | |
7994
8ccd9b0bf6bc
plot/axis.m (__get_tight_lims__): don't fail if data is not a vector
John W. Eaton <jwe@octave.org>
parents:
7376
diff
changeset
|
296 |
7376 | 297 endfunction |
298 | |
299 function __do_tight_option__ (ca) | |
300 | |
301 set (ca, | |
302 "xlim", __get_tight_lims__ (ca, "x"), | |
303 "ylim", __get_tight_lims__ (ca, "y"), | |
304 "zlim", __get_tight_lims__ (ca, "z")); | |
305 | |
306 endfunction | |
307 | |
308 | |
3667 | 309 %!demo |
310 %! t=0:0.01:2*pi; x=sin(t); | |
311 %! | |
312 %! subplot(221); title("normal plot"); | |
6746 | 313 %! plot(t, x); |
3667 | 314 %! |
315 %! subplot(222); title("square plot"); | |
6746 | 316 %! axis("square"); plot(t, x); |
3667 | 317 %! |
318 %! subplot(223); title("equal plot"); | |
6746 | 319 %! axis("equal"); plot(t, x); |
3667 | 320 %! |
321 %! subplot(224); title("normal plot again"); | |
6746 | 322 %! axis("normal"); plot(t, x); |
3667 | 323 |
324 %!demo | |
325 %! t=0:0.01:2*pi; x=sin(t); | |
326 %! | |
327 %! subplot(121); title("ij plot"); | |
6746 | 328 %! axis("ij"); plot(t, x); |
3667 | 329 %! |
330 %! subplot(122); title("xy plot"); | |
6746 | 331 %! axis("xy"); plot(t, x); |
3667 | 332 |
333 %!demo | |
334 %! t=0:0.01:2*pi; x=sin(t); | |
335 %! | |
336 %! subplot(331); title("x tics & labels"); | |
6746 | 337 %! axis("ticx"); plot(t, x); |
3667 | 338 %! |
339 %! subplot(332); title("y tics & labels"); | |
6746 | 340 %! axis("ticy"); plot(t, x); |
3667 | 341 %! |
342 %! subplot(334); title("x & y tics, x labels"); | |
6746 | 343 %! axis("labelx","tic"); plot(t, x); |
3667 | 344 %! |
345 %! subplot(335); title("x & y tics, y labels"); | |
6746 | 346 %! axis("labely","tic"); plot(t, x); |
3667 | 347 %! |
348 %! subplot(337); title("x tics, no labels"); | |
6746 | 349 %! axis("nolabel","ticx"); plot(t, x); |
3667 | 350 %! |
351 %! subplot(338); title("y tics, no labels"); | |
6746 | 352 %! axis("nolabel","ticy"); plot(t, x); |
3667 | 353 %! |
354 %! subplot(333); title("no tics or labels"); | |
6746 | 355 %! axis("off"); plot(t, x); |
3667 | 356 %! |
357 %! subplot(336); title("all tics but no labels"); | |
6746 | 358 %! axis("nolabel","tic"); plot(t, x); |
3667 | 359 %! |
360 %! subplot(339); title("all tics & labels"); | |
6746 | 361 %! axis("on"); plot(t, x); |
3667 | 362 |
363 %!demo | |
364 %! t=0:0.01:2*pi; x=sin(t); | |
365 %! | |
366 %! subplot(321); title("axes at [0 3 0 1]") | |
6746 | 367 %! axis([0,3,0,1]); plot(t, x); |
3667 | 368 %! |
369 %! subplot(322); title("auto"); | |
6746 | 370 %! axis("auto"); plot(t, x); |
3667 | 371 %! |
372 %! subplot(323); title("manual"); | |
373 %! plot(t, x, ";sine [0:2pi];"); hold on; | |
374 %! axis("manual"); | |
375 %! plot(-3:3,-3:3, ";line (-3,-3)->(3,3);"); hold off; | |
376 %! | |
377 %! subplot(324); title("axes at [0 3 0 1], then autox"); | |
378 %! axis([0,3,0,1]); axis("autox"); | |
379 %! plot(t, x, ";sine [0:2pi];"); | |
380 %! | |
381 %! subplot(325); title("axes at [3 6 0 1], then autoy"); | |
382 %! axis([3,6,0,1]); axis("autoy"); | |
383 %! plot(t, x, ";sine [0:2p];"); | |
384 %! | |
385 %! subplot(326); title("tight"); | |
6746 | 386 %! axis("tight"); plot(t, x); |
3667 | 387 %! % The last plot should not have any whitespace outside the data |
388 %! % limits, but "tight" isn't implemented yet. |