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