[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Changeset]: Ezplot
From: |
David Bateman |
Subject: |
[Changeset]: Ezplot |
Date: |
Wed, 20 Aug 2008 13:03:33 +0200 |
User-agent: |
Thunderbird 2.0.0.16 (X11/20080725) |
As discussed for the list of the 111 most used Matlab functions
http://www.jmatlab.org/benchmark.html
from Nick Higham, (see the thread
http://www.nabble.com/List-of-most-highly-used-matlab-functions.-to18693110.html)
I implemented the missing ezplot function based on the other ez* functions.
Regards
David
--
David Bateman address@hidden
Motorola Labs - Paris +33 1 69 35 48 04 (Ph)
Parc Les Algorithmes, Commune de St Aubin +33 6 72 01 06 33 (Mob)
91193 Gif-Sur-Yvette FRANCE +33 1 69 35 77 01 (Fax)
The information contained in this communication has been classified as:
[x] General Business Information
[ ] Motorola Internal Use Only
[ ] Motorola Confidential Proprietary
# HG changeset patch
# User David Bateman <address@hidden>
# Date 1219229704 -7200
# Node ID d2359741b3805ae14ab89a7f22338c91ceba5134
# Parent 920b816f97647551e27eadc9df52841aeb13c5d3
Add the ezplot function
diff --git a/doc/ChangeLog b/doc/ChangeLog
--- a/doc/ChangeLog
+++ b/doc/ChangeLog
@@ -1,3 +1,7 @@ 2008-08-19 David Bateman <address@hidden
+2008-08-20 David Bateman <address@hidden>
+
+ * interpreter/plot.txi: Document ezplot.
+
2008-08-19 David Bateman <address@hidden>
* interpreter/numbers.txi: Document intwarning.
diff --git a/doc/interpreter/plot.txi b/doc/interpreter/plot.txi
--- a/doc/interpreter/plot.txi
+++ b/doc/interpreter/plot.txi
@@ -208,7 +208,10 @@ legend displaying the name of the plotte
@DOCSTRING(fplot)
Other functions that can create two-dimensional plots directly from a
-function include @code{ezcontour}, @code{ezcontourf} and @code{ezpolar}.
+function include @code{ezplot), @code{ezcontour}, @code{ezcontourf} and
address@hidden
+
address@hidden(ezplot)
@DOCSTRING(ezcontour)
diff --git a/scripts/ChangeLog b/scripts/ChangeLog
--- a/scripts/ChangeLog
+++ b/scripts/ChangeLog
@@ -1,5 +1,9 @@ 2008-08-20 David Bateman <address@hidden
2008-08-20 David Bateman <address@hidden>
+ * plot/ezplot.m : New function.
+ * plot/Makefile.in (SOURCES): Add ezplot.m to the list.
+ * plot/__ezplot__.m: Adapt to allow for use with the ezplot function.
+
* plot/__go_draw_axes__.m: Don't set pm3d implicit if the plot
contains a surface. Fixes things like meshc(peaks()).
diff --git a/scripts/plot/Makefile.in b/scripts/plot/Makefile.in
--- a/scripts/plot/Makefile.in
+++ b/scripts/plot/Makefile.in
@@ -96,6 +96,7 @@ SOURCES = \
ezcontour.m \
ezmeshc.m \
ezmesh.m \
+ ezplot.m \
ezplot3.m \
ezpolar.m \
ezsurfc.m \
diff --git a/scripts/plot/__ezplot__.m b/scripts/plot/__ezplot__.m
--- a/scripts/plot/__ezplot__.m
+++ b/scripts/plot/__ezplot__.m
@@ -26,15 +26,23 @@ function [h, needusage] = __ezplot__ (pf
else
iscontour = false;
endif
- if (strcmp (pfunc, "plot3"))
+ if (strcmp (pfunc, "plot"))
+ isplot = true;
+ isplot3 = false;
+ ispolar = false;
+ nargs = 1;
+ elseif (strcmp (pfunc, "plot3"))
+ isplot = false;
isplot3 = true;
ispolar = false;
- nargs = 1
+ nargs = 1;
elseif (strcmp (pfunc, "polar"))
+ isplot = false;
isplot3 = false;
ispolar = true;
nargs = 1;
else
+ isplot = false;
isplot3 = false;
ispolar = false;
nargs = 2;
@@ -51,12 +59,25 @@ function [h, needusage] = __ezplot__ (pf
parametric = false;
fun = varargin {1};
if (ischar (fun))
- fun = vectorize (inline (fun));
- if (length (argnames (fun)) != nargs)
+ if (exist (fun, "file") || exist (fun, "builtin"))
+ fun = vectorize (inline (cstrcat (fun, "(t)")));
+ else
+ fun = vectorize (inline (fun));
+ endif
+ if (isplot && length (argnames (fun)) == 2)
+ nargs = 2;
+ elseif (length (argnames (fun)) != nargs)
error ("%s: excepting a function of %d arguments", func, nargs);
endif
fstr = formula (fun);
- if (isplot3)
+ if (isplot)
+ xarg = argnames(fun){1};
+ if (nargs == 2)
+ yarg = argnames(fun){2};
+ else
+ yarg = "";
+ endif
+ elseif (isplot3)
xarg = "x";
yarg = "y";
elseif (ispolar)
@@ -67,36 +88,58 @@ function [h, needusage] = __ezplot__ (pf
yarg = argnames(fun){2};
endif
elseif (strcmp (typeinfo (fun), "inline function"))
- if (length (argnames (fun)) != nargs)
+ if (isplot && length (argnames (fun)) == 2)
+ nargs = 2;
+ elseif (length (argnames (fun)) != nargs)
error ("%s: excepting a function of %d arguments", func, nargs);
endif
fun = vectorize (fun);
fstr = formula (fun);
- if (isplot3)
+ if (isplot)
+ xarg = argnames(fun){1};
+ if (nargs == 2)
+ yarg = argnames(fun){2};
+ else
+ yarg = "";
+ endif
+ elseif (isplot3)
+ xarg = "x";
+ yarg = "y";
+ elseif (isplot || ispolar)
+ xarg = "";
+ yarg = "";
+ else
+ xarg = argnames(fun)(1);
+ yarg = argnames(fun)(2);
+ endif
+ elseif (isa (fun, "function_handle"))
+ fstr = func2str (fun);
+ if (length (findstr (fstr, ")")) != 0)
+ args = regexp (substr (fstr, 3, findstr (fstr, ")")(1) - 3),
+ '(\w[\w\d]*)', 'tokens');
+ fstr = substr (fstr, findstr (fstr, ")")(1) + 1);
+ else
+ args = {{"x"}};
+ endif
+ if (isplot && length (args) == 2)
+ nargs = 2;
+ elseif (length (args) != nargs)
+ error ("%s: excepting a function of %d arguments", func, nargs);
+ endif
+ if (isplot)
+ xarg = args{1}{1};
+ if (nargs == 2)
+ yarg = args{2}{1};
+ else
+ yarg = "";
+ endif
+ elseif (isplot3)
xarg = "x";
yarg = "y";
elseif (ispolar)
xarg = "";
yarg = "";
else
- xarg = argnames(fun)(1);
- yarg = argnames(fun)(2);
- endif
- elseif (isa (fun, "function_handle"))
- fstr = func2str (fun);
- args = regexp (substr (fstr, 3, findstr (fstr, ")")(1) - 3),
- '(\w[\w\d]*)', 'tokens');
- if (length (args) != nargs)
- error ("%s: excepting a function of %d arguments", func, nargs);
- endif
- fstr = substr (fstr, findstr (fstr, ")")(1) + 1);
- if (isplot3)
- xarg = "x";
- yarg = "y";
- elseif (ispolar)
- xarg = "";
- yarg = "";
- else
xarg = args{1}{1};
yarg = args{2}{1};
endif
@@ -104,13 +147,17 @@ function [h, needusage] = __ezplot__ (pf
error ("%s: expecting string, inline function or function handle", func);
endif
- if (nargin > 2)
+ if (nargin > 2 || (nargin == 2 && isplot))
funx = fun;
fstrx = fstr;
funy = varargin {2};
if (ischar (funy) && ! strcmp (funy, "circ") && ! strcmp (funy, "animate"))
parametric = true;
- funy = vectorize (inline (funy));
+ if (exist (funy, "file") || exist (funy, "builtin"))
+ funy = vectorize (inline (cstrcat (funy, "(t)")));
+ else
+ funy = vectorize (inline (funy));
+ endif
if (length (argnames (funy)) != nargs)
error ("%s: excepting a function of %d arguments", func, nargs);
endif
@@ -125,19 +172,35 @@ function [h, needusage] = __ezplot__ (pf
elseif (isa (funy, "function_handle"))
parametric = true;
fstry = func2str (funy);
- args = regexp (substr (fstry, 3, findstr (fstry, ")")(1) - 3),
- '(\w[\w\d]*)', 'tokens');
+ if (length (findstr (fstry, ")")) != 0)
+ args = regexp (substr (fstry, 3, findstr (fstry, ")")(1) - 3),
+ '(\w[\w\d]*)', 'tokens');
+ fstry = substr (fstry, findstr (fstry, ")")(1) + 1);
+ else
+ args = {{"y"}};
+ endif
if (length (args) != nargs)
error ("%s: excepting a function of %d arguments", func, nargs);
endif
- fstry = substr (fstry, findstr (fstry, ")")(1) + 1);
- endif
-
- if (parametric)
+ endif
+
+ if (parametric && isplot)
+ xarg = "x";
+ yarg = "y";
+ if (nargs == 2)
+ error ("%s: can not define a parametric function in this manner");
+ endif
+ endif
+
+ if (!isplot && parametric)
funz = varargin {3};
if (ischar (funz) && ! strcmp (funz, "circ") &&
- ! strcmp (funy, "animate"))
- funz = vectorize (inline (funz));
+ ! strcmp (funz, "animate"))
+ if (exist (funz, "file") || exist (funz, "builtin"))
+ funz = vectorize (inline (cstrcat (funz, "(t)")));
+ else
+ funz = vectorize (inline (funz));
+ endif
if (length (argnames (funz)) != nargs)
error ("%s: excepting a function of %d arguments", func, nargs);
endif
@@ -162,12 +225,20 @@ function [h, needusage] = __ezplot__ (pf
endif
endif
- n = 60;
+ if (isplot && nargs != 2)
+ n = 500;
+ else
+ n = 60;
+ endif
domain = [];
circ = false;
animate = false;
if (parametric)
- iarg = 4;
+ if (isplot)
+ iarg = 3;
+ else
+ iarg = 4;
+ endif
else
iarg = 2;
endif
@@ -197,7 +268,7 @@ function [h, needusage] = __ezplot__ (pf
endif
if (circ)
- if (iscontour || isplot3)
+ if (iscontour || isplot3 || isplot)
needusage = true;
return;
endif
@@ -221,15 +292,23 @@ function [h, needusage] = __ezplot__ (pf
error ("%s: animated graphs not implemented", func);
endif
- if (isplot3 || ispolar)
+ if (isplot3 || ispolar || (isplot && nargs == 1))
X = linspace (domain (1), domain (2), n);
+ elseif (isplot && numel (domain) == 2)
+ x = linspace (domain (1), domain (2), n);
+ [X, Y] = meshgrid (x, x);
else
x = linspace (domain (1), domain (2), n);
y = linspace (domain (3), domain (4), n);
[X, Y] = meshgrid (x, y);
endif
+
if (parametric)
- if (isplot3)
+ if (isplot)
+ XX = feval (funx, X);
+ Z = feval (funy, X);
+ X = XX;
+ elseif (isplot3)
Z = feval (funz, X);
XX = feval (funx, X);
YY = feval (funy, X);
@@ -252,26 +331,77 @@ function [h, needusage] = __ezplot__ (pf
'\./', '/'), '[\.]*\*', '');
fstry = regexprep (regexprep (regexprep (fstry,'\.\^\s*','^'),
'\./', '/'), '[\.]*\*', '');
- fstrz = regexprep (regexprep (regexprep (fstrz,'\.\^\s*','^'),
- '\./', '/'), '[\.]*\*', '');
- fstr = cstrcat ("[",fstrx,",",fstry,",",fstrz,"]");
+ if (isplot)
+ fstr = cstrcat ("x = ",fstrx,", y = ",fstry);
+ else
+ fstrz = regexprep (regexprep (regexprep (fstrz,'\.\^\s*','^'),
+ '\./', '/'), '[\.]*\*', '');
+ fstr = cstrcat ("x = ",fstrx,",y = ",fstry,", z = ",fstrz);
+ endif
else
if (isplot3)
needusage = true;
return;
endif
- if (ispolar)
- Z = feval (fun, X);
- else
- Z = feval (fun, X, Y);
-
- ## Eliminate the singularities
- Z = __eliminate_sing__ (Z);
- endif
-
fstr = regexprep (regexprep (regexprep (fstr,'\.\^\s*','^'), '\./', '/'),
'[\.]*\*', '');
+ if (isplot && nargs == 2)
+ if (strcmp (typeinfo (fun), "inline function") &&
+ !isempty (strfind (formula (fun) , "=")))
+ fun = inline (cstrcat (strrep (formula (fun), "=", "- ("), ")"));
+ else
+ fstr = cstrcat (fstr, " = 0");
+ endif
+
+ Z = feval (fun, X, Y);
+
+ ## Matlab returns line objects for this case and so can't call
+ ## contour directly as it returns patch objects to allow colormaps
+ ## to work with contours. Therefore recreate the lines from the
+ ## output for contourc, and store in cell arrays.
+ [c, lev] = contourc (X, Y, Z, [0, 0]);
+
+ i1 = 1;
+ XX = {};
+ YY = {};
+ while (i1 < length (c))
+ clev = c(1,i1);
+ clen = c(2,i1);
+ XX = [XX, {c(1, i1+1:i1+clen)}];
+ YY = [YY, {c(2, i1+1:i1+clen)}];
+ i1 += clen+1;
+ endwhile
+ else
+ if (ispolar)
+ Z = feval (fun, X);
+ elseif (isplot)
+ Z = real (feval (fun, X));
+
+ ## Eliminate the singularities. This seems to be what matlab
+ ## does, but can't be sure.
+ XX = sort (Z (isfinite (Z)));
+ if (length (X) > 4)
+ d = XX(fix (7 * length (XX) / 8)) - XX(fix (length (XX) / 8));
+ yrange = [max(XX(1) - d/8, XX(fix (length (XX) / 8)) - d), ...
+ min(XX(end) + d/8, XX(fix (7 * length (XX) / 8)) + d)];
+ else
+ yrange = [XX(1), XX(end)];
+ endif
+
+ idx = 2 : length(Z);
+ idx = find (((Z(idx) > yrange(2) / 2) & (Z(idx-1) < yrange(1) / 2)) |
+ ((Z(idx) < yrange(1) / 2) & (Z(idx-1) > yrange (2) / 2)));
+ if (any(idx))
+ Z(idx) = NaN;
+ endif
+ else
+ Z = feval (fun, X, Y);
+
+ ## Eliminate the singularities
+ Z = __eliminate_sing__ (Z);
+ endif
+ endif
endif
oldax = gca ();
@@ -279,8 +409,21 @@ function [h, needusage] = __ezplot__ (pf
axes (ax);
if (iscontour)
[clev, h] = feval (pfunc, X, Y, Z);
- elseif (ispolar)
+ elseif (isplot && nargs == 2)
+ h = [];
+ hold_state = get (ax, "nextplot");
+ for i = 1 : length (XX)
+ h = [h; plot(XX{i}, YY{i})];
+ if (i == 1)
+ set (ax, "nextplot", "add")
+ endif
+ endfor
+ set (ax, "nextplot", hold_state)
+ elseif (ispolar || isplot)
h = feval (pfunc, X, Z);
+ if (isplot && !parametric)
+ axis ([X(1), X(end), yrange]);
+ endif
else
h = feval (pfunc, X, Y, Z);
endif
diff --git a/scripts/plot/ezplot.m b/scripts/plot/ezplot.m
new file mode 100644
--- /dev/null
+++ b/scripts/plot/ezplot.m
@@ -0,0 +1,89 @@
+## Copyright (C) 2008 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING. If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} ezplot (@var{f})
+## @deftypefnx {Function File} {} ezplot (@var{fx}, @var{fy})
+## @deftypefnx {Function File} {} ezplot (@dots{}, @var{dom})
+## @deftypefnx {Function File} {} ezplot (@dots{}, @var{n})
+## @deftypefnx {Function File} {} ezplot (@var{h}, @dots{})
+## @deftypefnx {Function File} address@hidden =} ezplot (@dots{})
+##
+## Plots in two-dimensions the curve defined by @var{f}. The function
+## @var{f} may be a string, inline function or function handle and can
+## have either one or two variables. If @var{f} has one variable, then
+## the function is plotted over the domain @code{-2*pi < @var{x} < 2*pi}
+## with 500 points.
+##
+## If @var{f} has two variables then @address@hidden(@var{x},@var{y}) = 0}
+## is calculated over the meshed domain @code{-2*pi < @var{x} | @var{y}
+## < 2*pi} with 60 by 60 in the mesh. For example
+##
+## @example
+## ezplot (@@(@var{x}, @var{y}) @var{x} .^ 2 - @var{y} .^ 2 - 1)
+## @end example
+##
+## If two functions are passed as strings, inline functions or function
+## handles, then the parametric function
+##
+## @example
+## @group
+## @var{x} = @var{fx} (@var{t})
+## @var{y} = @var{fy} (@var{t})
+## @end group
+## @end example
+##
+## is plotted over the domain @code{-2*pi < @var{t} < 2*pi} with 500
+## points.
+##
+## If @var{dom} is a two element vector, it represents the minimum and maximum
+## value of @var{x}, @var{y} and @var{t}. If it is a four element
+## vector, then the minimum and maximum values of @var{x} and @var{t}
+## are determined by the first two elements and the minimum and maximum
+## of @var{y} by the second pair of elements.
+##
+## @var{n} is a scalar defining the number of points to use in plotting
+## the function.
+##
+## The optional return value @var{h} provides a list of handles to the
+## the line objects plotted.
+##
+## @seealso{plot, ezplot3}
+## @end deftypefn
+
+function retval = ezplot (varargin)
+
+ [h, needusage] = __ezplot__ ("plot", varargin{:});
+
+ if (needusage)
+ print_usage ();
+ endif
+
+ if (nargout > 0)
+ retval = h;
+ endif
+endfunction
+
+%!demo
+%! ezplot (@cos, @sin)
+
+%!demo
+%! ezplot ("1/x")
+
+%!demo
+%! ezplot (inline("x^2 - y^2 = 1"))
- [Changeset]: Ezplot,
David Bateman <=