1 ## Copyright (C) 2007-2012 David Bateman
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} {[@var{h}, @var{needusage}] =} __ezplot__ (@var{pfunc}, @var{varargin})
21 ## Undocumented internal function.
24 function [h, needusage] = __ezplot__ (pfunc, varargin)
26 func = cstrcat ("ez", pfunc);
27 if (strncmp (pfunc, "contour", 7))
32 if (strcmp (pfunc, "plot"))
37 elseif (strcmp (pfunc, "plot3"))
42 elseif (strcmp (pfunc, "polar"))
54 [ax, varargin, nargin] = __plt_get_axis_arg__ (func, varargin{:});
65 if (exist (fun, "file") || exist (fun, "builtin"))
66 fun = vectorize (inline (cstrcat (fun, "(t)")));
68 fun = vectorize (inline (fun));
70 if (isplot && length (argnames (fun)) == 2)
72 elseif (length (argnames (fun)) != nargs)
73 error ("%s: excepting a function of %d arguments", func, nargs);
77 xarg = argnames(fun){1};
79 yarg = argnames(fun){2};
90 xarg = argnames(fun){1};
91 yarg = argnames(fun){2};
93 elseif (strcmp (typeinfo (fun), "inline function"))
94 if (isplot && length (argnames (fun)) == 2)
96 elseif (length (argnames (fun)) != nargs)
97 error ("%s: excepting a function of %d arguments", func, nargs);
99 fun = vectorize (fun);
100 fstr = formula (fun);
102 xarg = argnames(fun){1};
104 yarg = argnames(fun){2};
111 elseif (isplot || ispolar)
115 xarg = argnames(fun)(1);
116 yarg = argnames(fun)(2);
118 elseif (isa (fun, "function_handle"))
119 fstr = func2str (fun);
120 if (length (findstr (fstr, ")")) != 0)
121 args = regexp (substr (fstr, 3, findstr (fstr, ")")(1) - 3),
123 fstr = substr (fstr, findstr (fstr, ")")(1) + 1);
127 if (isplot && length (args) == 2)
129 elseif (length (args) != nargs)
130 error ("%s: excepting a function of %d arguments", func, nargs);
150 error ("%s: expecting string, inline function or function handle", func);
153 if (nargin > 2 || (nargin == 2 && isplot))
157 if (ischar (funy) && ! strcmp (funy, "circ") && ! strcmp (funy, "animate"))
159 if (exist (funy, "file") || exist (funy, "builtin"))
160 funy = vectorize (inline (cstrcat (funy, "(t)")));
162 funy = vectorize (inline (funy));
164 if (length (argnames (funy)) != nargs)
165 error ("%s: excepting a function of %d arguments", func, nargs);
167 fstry = formula (funy);
168 elseif (strcmp (typeinfo (funy), "inline function"))
170 if (length (argnames (funy)) != nargs)
171 error ("%s: excepting a function of %d arguments", func, nargs);
173 funy = vectorize (funy);
174 fstry = formula (funy);
175 elseif (isa (funy, "function_handle"))
177 fstry = func2str (funy);
178 if (length (findstr (fstry, ")")) != 0)
179 args = regexp (substr (fstry, 3, findstr (fstry, ")")(1) - 3),
181 fstry = substr (fstry, findstr (fstry, ")")(1) + 1);
185 if (length (args) != nargs)
186 error ("%s: excepting a function of %d arguments", func, nargs);
190 if (parametric && isplot)
194 error ("%s: can not define a parametric function in this manner");
198 if (!isplot && parametric)
200 if (ischar (funz) && ! strcmp (funz, "circ")
201 && ! strcmp (funz, "animate"))
202 if (exist (funz, "file") || exist (funz, "builtin"))
203 funz = vectorize (inline (cstrcat (funz, "(t)")));
205 funz = vectorize (inline (funz));
207 if (length (argnames (funz)) != nargs)
208 error ("%s: excepting a function of %d arguments", func, nargs);
210 fstrz = formula (funz);
211 elseif (strcmp (typeinfo (funz), "inline function"))
212 if (length (argnames (funz)) != nargs)
213 error ("%s: excepting a function of %d arguments", func, nargs);
215 funz = vectorize (funz);
216 fstrz = formula (funz);
217 elseif (isa (funz, "function_handle"))
218 fstrz = func2str (funz);
219 args = regexp (substr (fstrz, 3, findstr (fstrz, ")")(1) - 3),
221 if (length (args) != nargs)
222 error ("%s: excepting a function of %d arguments", func, nargs);
224 fstrz = substr (fstrz, findstr (fstrz, ")")(1) + 1);
226 error ("%s: parametric plots expect 3 functions", func);
231 if (isplot && nargs != 2)
248 while (iarg <= nargin)
249 arg = varargin{iarg++};
250 if (ischar (arg) && strcmp (arg, "circ"))
252 elseif (ischar (arg) && strcmp (arg, "animate"))
254 elseif (isscalar (arg))
256 elseif (numel (arg) == 2)
257 domain = [arg(:).' arg(:).'];
258 elseif (numel (arg) == 4)
261 error ("%s: expecting scalar, 2 or 4 element vector", func);
265 if (isempty (domain))
266 if (isplot3 || ispolar)
267 domain = [0, 2*pi, 0, 2*pi];
269 domain = [-2*pi, 2*pi, -2*pi, 2*pi];
274 if (iscontour || isplot3 || isplot)
279 error ("%s: can not have both circular domain and parametric function",
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), ...
293 error ("%s: animated graphs only valid with plot3", func);
295 error ("%s: animated graphs not implemented", func);
298 if (isplot3 || ispolar || (isplot && nargs == 1))
299 X = linspace (domain (1), domain (2), n);
300 elseif (isplot && numel (domain) == 2)
301 x = linspace (domain (1), domain (2), n);
302 [X, Y] = meshgrid (x, x);
304 x = linspace (domain (1), domain (2), n);
305 y = linspace (domain (3), domain (4), n);
306 [X, Y] = meshgrid (x, y);
311 XX = feval (funx, X);
316 XX = feval (funx, X);
317 YY = feval (funy, X);
321 Z = feval (funz, X, Y);
322 XX = feval (funx, X, Y);
323 YY = feval (funy, X, Y);
327 ## Eliminate the singularities
328 X = __eliminate_sing__ (X);
329 Y = __eliminate_sing__ (Y);
330 Z = __eliminate_sing__ (Z);
333 fstrx = regexprep (regexprep (regexprep (fstrx,'\s*\.?\^\s*','^'),
334 '\./', '/'), '\.?\*', '');
335 fstry = regexprep (regexprep (regexprep (fstry,'\s*\.?\^\s*','^'),
336 '\./', '/'), '\.?\*', '');
338 fstr = cstrcat ("x = ",fstrx,", y = ",fstry);
340 fstrz = regexprep (regexprep (regexprep (fstrz,'\s*\.?\^\s*','^'),
341 '\./', '/'), '\.?\*', '');
342 fstr = cstrcat ("x = ",fstrx,",y = ",fstry,", z = ",fstrz);
350 fstr = regexprep (regexprep (regexprep (fstr,'\s*\.?\^\s*','^'), '\./', '/'),
352 if (isplot && nargs == 2)
353 if (strcmp (typeinfo (fun), "inline function")
354 && !isempty (strfind (formula (fun) , "=")))
355 fun = inline (cstrcat (strrep (formula (fun), "=", "- ("), ")"));
357 fstr = cstrcat (fstr, " = 0");
360 Z = feval (fun, X, Y);
362 ## Matlab returns line objects for this case and so can't call
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]);
371 while (i1 < length (c))
374 XX = [XX, {c(1, i1+1:i1+clen)}];
375 YY = [YY, {c(2, i1+1:i1+clen)}];
382 Z = real (feval (fun, X));
384 ## Eliminate the singularities. This seems to be what matlab
385 ## does, but can't be sure.
386 XX = sort (Z (isfinite (Z)));
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)];
392 yrange = [XX(1), XX(end)];
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)));
402 Z = feval (fun, X, Y);
404 ## Eliminate the singularities
405 Z = __eliminate_sing__ (Z);
414 [clev, h] = feval (pfunc, X, Y, Z);
415 elseif (isplot && nargs == 2)
417 hold_state = get (ax, "nextplot");
418 for i = 1 : length (XX)
419 h = [h; plot(XX{i}, YY{i})];
421 set (ax, "nextplot", "add");
424 set (ax, "nextplot", hold_state);
425 elseif (ispolar || isplot)
426 h = feval (pfunc, X, Z);
427 if (isplot && !parametric)
428 axis ([X(1), X(end), yrange]);
431 h = feval (pfunc, X, Y, Z);
436 unwind_protect_cleanup
442 function x = __eliminate_sing__ (x)
444 x (abs (del2 (x)) > 0.2 * (max(x(:)) - min(x(:)))) = NaN;