Mercurial > hg > octave-lyh
annotate scripts/plot/private/__ezplot__.m @ 14138:72c96de7a403 stable
maint: update copyright notices for 2012
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Mon, 02 Jan 2012 14:25:41 -0500 |
parents | b0084095098e |
children | 2fe0f5fa8cc3 |
rev | line source |
---|---|
14138
72c96de7a403
maint: update copyright notices for 2012
John W. Eaton <jwe@octave.org>
parents:
11589
diff
changeset
|
1 ## Copyright (C) 2007-2012 David Bateman |
7337 | 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 | |
8812
7d48766c21a5
use consistent format for doc strings of internal functions
John W. Eaton <jwe@octave.org>
parents:
8046
diff
changeset
|
19 ## -*- texinfo -*- |
7d48766c21a5
use consistent format for doc strings of internal functions
John W. Eaton <jwe@octave.org>
parents:
8046
diff
changeset
|
20 ## @deftypefn {Function File} {[@var{h}, @var{needusage}] =} __ezplot__ (@var{pfunc}, @var{varargin}) |
7d48766c21a5
use consistent format for doc strings of internal functions
John W. Eaton <jwe@octave.org>
parents:
8046
diff
changeset
|
21 ## Undocumented internal function. |
7d48766c21a5
use consistent format for doc strings of internal functions
John W. Eaton <jwe@octave.org>
parents:
8046
diff
changeset
|
22 ## @end deftypefn |
7337 | 23 |
24 function [h, needusage] = __ezplot__ (pfunc, varargin) | |
25 | |
7540
3422f39573b1
strcat.m: Matlab compatibility, with cstrcat.m replacing conventional strcat.m.
Ben Abbott <bpabbott@mac.com>
parents:
7337
diff
changeset
|
26 func = cstrcat ("ez", pfunc); |
7337 | 27 if (strncmp (pfunc, "contour", 7)) |
28 iscontour = true; | |
29 else | |
30 iscontour = false; | |
31 endif | |
8046 | 32 if (strcmp (pfunc, "plot")) |
33 isplot = true; | |
34 isplot3 = false; | |
35 ispolar = false; | |
36 nargs = 1; | |
37 elseif (strcmp (pfunc, "plot3")) | |
38 isplot = false; | |
7337 | 39 isplot3 = true; |
40 ispolar = false; | |
8046 | 41 nargs = 1; |
7337 | 42 elseif (strcmp (pfunc, "polar")) |
8046 | 43 isplot = false; |
7337 | 44 isplot3 = false; |
45 ispolar = true; | |
46 nargs = 1; | |
47 else | |
8046 | 48 isplot = false; |
7337 | 49 isplot3 = false; |
50 ispolar = false; | |
51 nargs = 2; | |
52 endif | |
53 | |
54 [ax, varargin, nargin] = __plt_get_axis_arg__ (func, varargin{:}); | |
55 | |
56 needusage = false; | |
57 if (nargin < 1) | |
58 needusage = true; | |
59 return; | |
60 endif | |
61 | |
62 parametric = false; | |
63 fun = varargin {1}; | |
64 if (ischar (fun)) | |
8046 | 65 if (exist (fun, "file") || exist (fun, "builtin")) |
66 fun = vectorize (inline (cstrcat (fun, "(t)"))); | |
67 else | |
68 fun = vectorize (inline (fun)); | |
69 endif | |
70 if (isplot && length (argnames (fun)) == 2) | |
71 nargs = 2; | |
72 elseif (length (argnames (fun)) != nargs) | |
7337 | 73 error ("%s: excepting a function of %d arguments", func, nargs); |
74 endif | |
75 fstr = formula (fun); | |
8046 | 76 if (isplot) |
77 xarg = argnames(fun){1}; | |
78 if (nargs == 2) | |
10549 | 79 yarg = argnames(fun){2}; |
8046 | 80 else |
10549 | 81 yarg = ""; |
8046 | 82 endif |
83 elseif (isplot3) | |
7337 | 84 xarg = "x"; |
85 yarg = "y"; | |
86 elseif (ispolar) | |
87 xarg = ""; | |
88 yarg = ""; | |
89 else | |
90 xarg = argnames(fun){1}; | |
91 yarg = argnames(fun){2}; | |
92 endif | |
93 elseif (strcmp (typeinfo (fun), "inline function")) | |
8046 | 94 if (isplot && length (argnames (fun)) == 2) |
95 nargs = 2; | |
96 elseif (length (argnames (fun)) != nargs) | |
7337 | 97 error ("%s: excepting a function of %d arguments", func, nargs); |
98 endif | |
99 fun = vectorize (fun); | |
100 fstr = formula (fun); | |
8046 | 101 if (isplot) |
102 xarg = argnames(fun){1}; | |
103 if (nargs == 2) | |
10549 | 104 yarg = argnames(fun){2}; |
8046 | 105 else |
10549 | 106 yarg = ""; |
8046 | 107 endif |
108 elseif (isplot3) | |
7337 | 109 xarg = "x"; |
110 yarg = "y"; | |
8046 | 111 elseif (isplot || ispolar) |
7337 | 112 xarg = ""; |
113 yarg = ""; | |
114 else | |
115 xarg = argnames(fun)(1); | |
116 yarg = argnames(fun)(2); | |
117 endif | |
118 elseif (isa (fun, "function_handle")) | |
119 fstr = func2str (fun); | |
8046 | 120 if (length (findstr (fstr, ")")) != 0) |
11587
c792872f8942
all script files: untabify and strip trailing whitespace
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
121 args = regexp (substr (fstr, 3, findstr (fstr, ")")(1) - 3), |
11032
c9b0a75b02e8
Make all regexp in Octave compatible with both POSIX and PCRE.
Rik <octave@nomad.inbox5.com>
parents:
10549
diff
changeset
|
122 '(\w+)', 'tokens'); |
8046 | 123 fstr = substr (fstr, findstr (fstr, ")")(1) + 1); |
124 else | |
125 args = {{"x"}}; | |
126 endif | |
127 if (isplot && length (args) == 2) | |
128 nargs = 2; | |
129 elseif (length (args) != nargs) | |
7337 | 130 error ("%s: excepting a function of %d arguments", func, nargs); |
131 endif | |
8046 | 132 if (isplot) |
133 xarg = args{1}{1}; | |
134 if (nargs == 2) | |
10549 | 135 yarg = args{2}{1}; |
8046 | 136 else |
10549 | 137 yarg = ""; |
8046 | 138 endif |
139 elseif (isplot3) | |
7337 | 140 xarg = "x"; |
141 yarg = "y"; | |
142 elseif (ispolar) | |
143 xarg = ""; | |
144 yarg = ""; | |
145 else | |
146 xarg = args{1}{1}; | |
147 yarg = args{2}{1}; | |
148 endif | |
149 else | |
150 error ("%s: expecting string, inline function or function handle", func); | |
151 endif | |
152 | |
8046 | 153 if (nargin > 2 || (nargin == 2 && isplot)) |
7337 | 154 funx = fun; |
155 fstrx = fstr; | |
156 funy = varargin {2}; | |
157 if (ischar (funy) && ! strcmp (funy, "circ") && ! strcmp (funy, "animate")) | |
158 parametric = true; | |
8046 | 159 if (exist (funy, "file") || exist (funy, "builtin")) |
10549 | 160 funy = vectorize (inline (cstrcat (funy, "(t)"))); |
8046 | 161 else |
10549 | 162 funy = vectorize (inline (funy)); |
8046 | 163 endif |
7337 | 164 if (length (argnames (funy)) != nargs) |
10549 | 165 error ("%s: excepting a function of %d arguments", func, nargs); |
7337 | 166 endif |
167 fstry = formula (funy); | |
168 elseif (strcmp (typeinfo (funy), "inline function")) | |
169 parametric = true; | |
170 if (length (argnames (funy)) != nargs) | |
10549 | 171 error ("%s: excepting a function of %d arguments", func, nargs); |
7337 | 172 endif |
173 funy = vectorize (funy); | |
174 fstry = formula (funy); | |
175 elseif (isa (funy, "function_handle")) | |
176 parametric = true; | |
177 fstry = func2str (funy); | |
8046 | 178 if (length (findstr (fstry, ")")) != 0) |
11587
c792872f8942
all script files: untabify and strip trailing whitespace
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
179 args = regexp (substr (fstry, 3, findstr (fstry, ")")(1) - 3), |
11032
c9b0a75b02e8
Make all regexp in Octave compatible with both POSIX and PCRE.
Rik <octave@nomad.inbox5.com>
parents:
10549
diff
changeset
|
180 '(\w+)', 'tokens'); |
10549 | 181 fstry = substr (fstry, findstr (fstry, ")")(1) + 1); |
8046 | 182 else |
10549 | 183 args = {{"y"}}; |
8046 | 184 endif |
7337 | 185 if (length (args) != nargs) |
10549 | 186 error ("%s: excepting a function of %d arguments", func, nargs); |
7337 | 187 endif |
8046 | 188 endif |
189 | |
190 if (parametric && isplot) | |
191 xarg = "x"; | |
192 yarg = "y"; | |
193 if (nargs == 2) | |
10549 | 194 error ("%s: can not define a parametric function in this manner"); |
8046 | 195 endif |
7337 | 196 endif |
197 | |
8046 | 198 if (!isplot && parametric) |
7337 | 199 funz = varargin {3}; |
11149
fe3c3dfc07eb
style fix: break lines before && and ||, not after
John W. Eaton <jwe@octave.org>
parents:
11032
diff
changeset
|
200 if (ischar (funz) && ! strcmp (funz, "circ") |
fe3c3dfc07eb
style fix: break lines before && and ||, not after
John W. Eaton <jwe@octave.org>
parents:
11032
diff
changeset
|
201 && ! strcmp (funz, "animate")) |
10549 | 202 if (exist (funz, "file") || exist (funz, "builtin")) |
203 funz = vectorize (inline (cstrcat (funz, "(t)"))); | |
204 else | |
205 funz = vectorize (inline (funz)); | |
206 endif | |
207 if (length (argnames (funz)) != nargs) | |
208 error ("%s: excepting a function of %d arguments", func, nargs); | |
209 endif | |
210 fstrz = formula (funz); | |
7337 | 211 elseif (strcmp (typeinfo (funz), "inline function")) |
10549 | 212 if (length (argnames (funz)) != nargs) |
213 error ("%s: excepting a function of %d arguments", func, nargs); | |
214 endif | |
215 funz = vectorize (funz); | |
216 fstrz = formula (funz); | |
7337 | 217 elseif (isa (funz, "function_handle")) |
10549 | 218 fstrz = func2str (funz); |
11587
c792872f8942
all script files: untabify and strip trailing whitespace
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
219 args = regexp (substr (fstrz, 3, findstr (fstrz, ")")(1) - 3), |
11032
c9b0a75b02e8
Make all regexp in Octave compatible with both POSIX and PCRE.
Rik <octave@nomad.inbox5.com>
parents:
10549
diff
changeset
|
220 '(\w+)', 'tokens'); |
10549 | 221 if (length (args) != nargs) |
222 error ("%s: excepting a function of %d arguments", func, nargs); | |
223 endif | |
224 fstrz = substr (fstrz, findstr (fstrz, ")")(1) + 1); | |
7337 | 225 else |
10549 | 226 error ("%s: parametric plots expect 3 functions", func); |
7337 | 227 endif |
228 endif | |
229 endif | |
230 | |
8046 | 231 if (isplot && nargs != 2) |
11587
c792872f8942
all script files: untabify and strip trailing whitespace
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
232 n = 500; |
8046 | 233 else |
234 n = 60; | |
235 endif | |
7337 | 236 domain = []; |
237 circ = false; | |
238 animate = false; | |
239 if (parametric) | |
8046 | 240 if (isplot) |
241 iarg = 3; | |
242 else | |
243 iarg = 4; | |
244 endif | |
7337 | 245 else |
246 iarg = 2; | |
247 endif | |
248 while (iarg <= nargin) | |
249 arg = varargin{iarg++}; | |
250 if (ischar (arg) && strcmp (arg, "circ")) | |
251 circ = true; | |
252 elseif (ischar (arg) && strcmp (arg, "animate")) | |
253 animate = true; | |
254 elseif (isscalar (arg)) | |
255 n = arg; | |
256 elseif (numel (arg) == 2) | |
257 domain = [arg(:).' arg(:).']; | |
258 elseif (numel (arg) == 4) | |
259 domain = arg(:).'; | |
260 else | |
261 error ("%s: expecting scalar, 2 or 4 element vector", func); | |
262 endif | |
263 endwhile | |
264 | |
265 if (isempty (domain)) | |
266 if (isplot3 || ispolar) | |
267 domain = [0, 2*pi, 0, 2*pi]; | |
268 else | |
269 domain = [-2*pi, 2*pi, -2*pi, 2*pi]; | |
270 endif | |
271 endif | |
272 | |
273 if (circ) | |
8046 | 274 if (iscontour || isplot3 || isplot) |
7337 | 275 needusage = true; |
276 return; | |
277 endif | |
278 if (parametric) | |
11587
c792872f8942
all script files: untabify and strip trailing whitespace
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
279 error ("%s: can not have both circular domain and parametric function", |
10549 | 280 func); |
7337 | 281 endif |
282 cent = [domain(1) + domain(2), domain(3) + domain(4)] / 2; | |
283 funx = @(r,t) r .* cos (t) + cent (1); | |
284 funy = @(r,t) r .* sin (t) + cent (2); | |
285 domain = [0, sqrt((domain(2) - cent(1))^2 + (domain(4) - cent(2))^2), ... | |
10549 | 286 -pi, pi]; |
7337 | 287 funz = fun; |
288 parametric = true; | |
289 endif | |
290 | |
291 if (animate) | |
292 if (!isplot3) | |
293 error ("%s: animated graphs only valid with plot3", func); | |
294 endif | |
295 error ("%s: animated graphs not implemented", func); | |
296 endif | |
297 | |
8046 | 298 if (isplot3 || ispolar || (isplot && nargs == 1)) |
7337 | 299 X = linspace (domain (1), domain (2), n); |
8046 | 300 elseif (isplot && numel (domain) == 2) |
301 x = linspace (domain (1), domain (2), n); | |
302 [X, Y] = meshgrid (x, x); | |
7337 | 303 else |
304 x = linspace (domain (1), domain (2), n); | |
305 y = linspace (domain (3), domain (4), n); | |
306 [X, Y] = meshgrid (x, y); | |
307 endif | |
8046 | 308 |
7337 | 309 if (parametric) |
8046 | 310 if (isplot) |
311 XX = feval (funx, X); | |
312 Z = feval (funy, X); | |
313 X = XX; | |
314 elseif (isplot3) | |
7337 | 315 Z = feval (funz, X); |
316 XX = feval (funx, X); | |
317 YY = feval (funy, X); | |
318 X = XX; | |
319 Y = YY; | |
320 else | |
321 Z = feval (funz, X, Y); | |
322 XX = feval (funx, X, Y); | |
323 YY = feval (funy, X, Y); | |
324 X = XX; | |
325 Y = YY; | |
326 | |
327 ## Eliminate the singularities | |
328 X = __eliminate_sing__ (X); | |
329 Y = __eliminate_sing__ (Y); | |
330 Z = __eliminate_sing__ (Z); | |
331 endif | |
332 | |
11587
c792872f8942
all script files: untabify and strip trailing whitespace
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
333 fstrx = regexprep (regexprep (regexprep (fstrx,'\s*\.?\^\s*','^'), |
11032
c9b0a75b02e8
Make all regexp in Octave compatible with both POSIX and PCRE.
Rik <octave@nomad.inbox5.com>
parents:
10549
diff
changeset
|
334 '\./', '/'), '\.?\*', ''); |
11587
c792872f8942
all script files: untabify and strip trailing whitespace
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
335 fstry = regexprep (regexprep (regexprep (fstry,'\s*\.?\^\s*','^'), |
11032
c9b0a75b02e8
Make all regexp in Octave compatible with both POSIX and PCRE.
Rik <octave@nomad.inbox5.com>
parents:
10549
diff
changeset
|
336 '\./', '/'), '\.?\*', ''); |
8046 | 337 if (isplot) |
338 fstr = cstrcat ("x = ",fstrx,", y = ",fstry); | |
339 else | |
11587
c792872f8942
all script files: untabify and strip trailing whitespace
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
340 fstrz = regexprep (regexprep (regexprep (fstrz,'\s*\.?\^\s*','^'), |
11032
c9b0a75b02e8
Make all regexp in Octave compatible with both POSIX and PCRE.
Rik <octave@nomad.inbox5.com>
parents:
10549
diff
changeset
|
341 '\./', '/'), '\.?\*', ''); |
8046 | 342 fstr = cstrcat ("x = ",fstrx,",y = ",fstry,", z = ",fstrz); |
343 endif | |
7337 | 344 else |
345 if (isplot3) | |
346 needusage = true; | |
347 return; | |
348 endif | |
349 | |
11587
c792872f8942
all script files: untabify and strip trailing whitespace
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
350 fstr = regexprep (regexprep (regexprep (fstr,'\s*\.?\^\s*','^'), '\./', '/'), |
11032
c9b0a75b02e8
Make all regexp in Octave compatible with both POSIX and PCRE.
Rik <octave@nomad.inbox5.com>
parents:
10549
diff
changeset
|
351 '\.?\*', ''); |
8046 | 352 if (isplot && nargs == 2) |
11149
fe3c3dfc07eb
style fix: break lines before && and ||, not after
John W. Eaton <jwe@octave.org>
parents:
11032
diff
changeset
|
353 if (strcmp (typeinfo (fun), "inline function") |
fe3c3dfc07eb
style fix: break lines before && and ||, not after
John W. Eaton <jwe@octave.org>
parents:
11032
diff
changeset
|
354 && !isempty (strfind (formula (fun) , "="))) |
10549 | 355 fun = inline (cstrcat (strrep (formula (fun), "=", "- ("), ")")); |
8046 | 356 else |
10549 | 357 fstr = cstrcat (fstr, " = 0"); |
8046 | 358 endif |
359 | |
7337 | 360 Z = feval (fun, X, Y); |
361 | |
11587
c792872f8942
all script files: untabify and strip trailing whitespace
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
362 ## Matlab returns line objects for this case and so can't call |
8046 | 363 ## contour directly as it returns patch objects to allow colormaps |
364 ## to work with contours. Therefore recreate the lines from the | |
365 ## output for contourc, and store in cell arrays. | |
366 [c, lev] = contourc (X, Y, Z, [0, 0]); | |
367 | |
368 i1 = 1; | |
369 XX = {}; | |
370 YY = {}; | |
371 while (i1 < length (c)) | |
10549 | 372 clev = c(1,i1); |
373 clen = c(2,i1); | |
374 XX = [XX, {c(1, i1+1:i1+clen)}]; | |
375 YY = [YY, {c(2, i1+1:i1+clen)}]; | |
376 i1 += clen+1; | |
8046 | 377 endwhile |
11587
c792872f8942
all script files: untabify and strip trailing whitespace
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
378 else |
8046 | 379 if (ispolar) |
10549 | 380 Z = feval (fun, X); |
8046 | 381 elseif (isplot) |
10549 | 382 Z = real (feval (fun, X)); |
8046 | 383 |
10549 | 384 ## Eliminate the singularities. This seems to be what matlab |
385 ## does, but can't be sure. | |
386 XX = sort (Z (isfinite (Z))); | |
387 if (length (X) > 4) | |
388 d = XX(fix (7 * length (XX) / 8)) - XX(fix (length (XX) / 8)); | |
389 yrange = [max(XX(1) - d/8, XX(fix (length (XX) / 8)) - d), ... | |
390 min(XX(end) + d/8, XX(fix (7 * length (XX) / 8)) + d)]; | |
391 else | |
392 yrange = [XX(1), XX(end)]; | |
8046 | 393 endif |
394 | |
10549 | 395 idx = 2 : length(Z); |
396 idx = find (((Z(idx) > yrange(2) / 2) & (Z(idx-1) < yrange(1) / 2)) | | |
397 ((Z(idx) < yrange(1) / 2) & (Z(idx-1) > yrange (2) / 2))); | |
398 if (any(idx)) | |
11587
c792872f8942
all script files: untabify and strip trailing whitespace
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
399 Z(idx) = NaN; |
10549 | 400 endif |
8046 | 401 else |
10549 | 402 Z = feval (fun, X, Y); |
8046 | 403 |
10549 | 404 ## Eliminate the singularities |
405 Z = __eliminate_sing__ (Z); | |
8046 | 406 endif |
7337 | 407 endif |
408 endif | |
409 | |
11587
c792872f8942
all script files: untabify and strip trailing whitespace
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
410 oldax = gca (); |
7337 | 411 unwind_protect |
412 axes (ax); | |
413 if (iscontour) | |
414 [clev, h] = feval (pfunc, X, Y, Z); | |
8046 | 415 elseif (isplot && nargs == 2) |
416 h = []; | |
417 hold_state = get (ax, "nextplot"); | |
418 for i = 1 : length (XX) | |
10549 | 419 h = [h; plot(XX{i}, YY{i})]; |
420 if (i == 1) | |
11589
b0084095098e
missing semicolons in script files
John W. Eaton <jwe@octave.org>
parents:
11587
diff
changeset
|
421 set (ax, "nextplot", "add"); |
10549 | 422 endif |
8046 | 423 endfor |
11589
b0084095098e
missing semicolons in script files
John W. Eaton <jwe@octave.org>
parents:
11587
diff
changeset
|
424 set (ax, "nextplot", hold_state); |
8046 | 425 elseif (ispolar || isplot) |
7337 | 426 h = feval (pfunc, X, Z); |
8046 | 427 if (isplot && !parametric) |
10549 | 428 axis ([X(1), X(end), yrange]); |
8046 | 429 endif |
7337 | 430 else |
431 h = feval (pfunc, X, Y, Z); | |
432 endif | |
433 xlabel (xarg); | |
434 ylabel (yarg); | |
435 title (fstr); | |
436 unwind_protect_cleanup | |
437 axes (oldax); | |
438 end_unwind_protect | |
439 | |
440 endfunction | |
441 | |
442 function x = __eliminate_sing__ (x) | |
443 x (isinf (x)) = NaN; | |
444 x (abs (del2 (x)) > 0.2 * (max(x(:)) - min(x(:)))) = NaN; | |
445 endfunction |