# HG changeset patch # User Rik # Date 1374732766 25200 # Node ID 9fe930c5abbf049b57b3fae9f82fb7e8a45269b3 # Parent 27b3a675ea6ba126a2496dbf562a4c774c2d5792 plot3.m: Update to use __plt_get_axis_arg__ and newplot. * scripts/plot/plot3.m: Update to use __plt_get_axis_arg__ and newplot. Redo docstring. Add second %!demo. diff --git a/scripts/plot/plot3.m b/scripts/plot/plot3.m --- a/scripts/plot/plot3.m +++ b/scripts/plot/plot3.m @@ -17,9 +17,17 @@ ## . ## -*- texinfo -*- -## @deftypefn {Function File} {} plot3 (@var{args}) -## Produce three-dimensional plots. Many different combinations of -## arguments are possible. The simplest form is +## @deftypefn {Function File} {} plot3 (@var{x}, @var{y}, @var{z}) +## @deftypefnx {Function File} {} plot3 (@var{x}, @var{y}, @var{z}, @var{property}, @var{value}, @dots{}) +## @deftypefnx {Function File} {} plot3 (@var{x}, @var{y}, @var{z}, @var{fmt}) +## @deftypefnx {Function File} {} plot3 (@var{x}, @var{cplx}) +## @deftypefnx {Function File} {} plot3 (@var{cplx}) +## @deftypefnx {Function File} {} plot3 (@var{hax}, @dots{}) +## @deftypefnx {Function File} {@var{h} =} plot3 (@dots{}) +## Produce three-dimensional plots. +## +## Many different combinations of arguments are possible. The simplest +## form is ## ## @example ## plot3 (@var{x}, @var{y}, @var{z}) @@ -29,14 +37,13 @@ ## in which the arguments are taken to be the vertices of the points to ## be plotted in three dimensions. If all arguments are vectors of the ## same length, then a single continuous line is drawn. If all arguments -## are matrices, then each column of the matrices is treated as a -## separate line. No attempt is made to transpose the arguments to make -## the number of rows match. +## are matrices, then each column of is treated as a separate line. No attempt +## is made to transpose the arguments to make the number of rows match. ## ## If only two arguments are given, as ## ## @example -## plot3 (@var{x}, @var{c}) +## plot3 (@var{x}, @var{cplx}) ## @end example ## ## @noindent @@ -46,7 +53,7 @@ ## If only one argument is given, as ## ## @example -## plot3 (@var{c}) +## plot3 (@var{cplx}) ## @end example ## ## @noindent @@ -70,6 +77,15 @@ ## plot3 (@var{x1}, @var{c1}, "", @var{c2}, "", @dots{}) ## @end example ## +## Multiple property-value pairs may be specified which will affect the line +## objects drawn by @code{plot3}. If the @var{fmt} argument is supplied it +## will format the line objects in the same manner as @code{plot}. +## +## If the first argument is an axis handle @var{hax}, then plot into these axes, +## rather than the current axis handle returned by @code{gca}. +## +## The optional return value @var{h} is a graphics handle to the created plot. +## ## An example of the use of @code{plot3} is ## ## @example @@ -79,7 +95,7 @@ ## plot3 (z, exp (2i*pi*z), ";complex sinusoid;"); ## @end group ## @end example -## @seealso{plot, xlabel, ylabel, zlabel, title, print} +## @seealso{ezplot3, plot} ## @end deftypefn ## Author: Paul Kienzle @@ -87,73 +103,209 @@ function retval = plot3 (varargin) - newplot (); + [hax, varargin, nargs] = __plt_get_axis_arg__ ("plot3", varargin{:}); + + if (nargs < 1) + print_usage (); + endif + + oldfig = ifelse (isempty (hax), [], get (0, "currentfigure")); + unwind_protect + hax = newplot (hax); + + x_set = 0; + y_set = 0; + z_set = 0; + property_set = 0; + fmt_set = 0; + properties = {}; + tlgnd = {}; + hlgnd = []; + idx = 0; + + ## Gather arguments, decode format, and plot lines. + arg = 0; + while (arg++ < nargs) + new = varargin{arg}; + new_cell = varargin(arg); + + if (property_set) + properties = [properties, new_cell]; + property_set = 0; + continue; + endif + + if (ischar (new)) + if (! z_set) + if (! y_set) + if (! x_set) + error ("plot3: needs X, [ Y, [ Z ] ]"); + else + y = real (x); + z = imag (x); + y_set = 1; + z_set = 1; + if (rows (x) > 1) + x = repmat ((1:rows (x))', 1, columns (x)); + else + x = 1:columns (x); + endif + endif + else + z = imag (y); + y = real (y); + z_set = 1; + endif + endif + + if (! fmt_set) + [options, valid] = __pltopt__ ("plot3", new, false); + if (! valid) + properties = [properties, new_cell]; + property_set = 1; + continue; + else + fmt_set = 1; + while (arg < nargs && ischar (varargin{arg+1})) + if (nargs - arg < 2) + error ("plot3: properties must appear followed by a value"); + endif + properties = [properties, varargin(arg+1:arg+2)]; + arg += 2; + endwhile + endif + else + properties = [properties, new_cell]; + property_set = 1; + continue; + endif + + if (isvector (x) && isvector (y)) + if (isvector (z)) + x = x(:); + y = y(:); + z = z(:); + elseif (length (x) == rows (z) && length (y) == columns (z)) + [x, y] = meshgrid (x, y); + else + error ("plot3: [length(X), length(Y)] must match size (Z)"); + endif + endif - x_set = 0; - y_set = 0; - z_set = 0; - property_set = 0; - fmt_set = 0; - properties = {}; - tlgnd = {}; - hlgnd = []; - idx = 0; + if (! size_equal (x, y, z)) + error ("plot3: X, Y, and Z must have the same shape"); + elseif (ndims (x) > 2) + error ("plot3: X, Y, and Z must not have more than two dimensions"); + endif + + for i = 1 : columns (x) + linestyle = options.linestyle; + marker = options.marker; + if (isempty (marker) && isempty (linestyle)) + [linestyle, marker] = __next_line_style__ (); + endif + color = options.color; + if (isempty (color)) + color = __next_line_color__ (); + endif + + htmp(++idx) = line (hax, x(:, i), y(:, i), z(:, i), + "color", color, "linestyle", linestyle, + "marker", marker, properties{:}); + key = options.key; + if (! isempty (key)) + hlgnd = [hlgnd, htmp(idx)]; + tlgnd = {tlgnd{:}, key}; + endif + endfor - ## Gather arguments, decode format, and plot lines. - arg = 0; - while (arg++ < nargin) - new = varargin{arg}; - new_cell = varargin(arg); + x_set = 0; + y_set = 0; + z_set = 0; + fmt_set = 0; + properties = {}; + elseif (! x_set) + x = new; + x_set = 1; + elseif (! y_set) + y = new; + y_set = 1; + elseif (! z_set) + z = new; + z_set = 1; + else + if (isvector (x) && isvector (y)) + if (isvector (z)) + x = x(:); + y = y(:); + z = z(:); + elseif (length (x) == rows (z) && length (y) == columns (z)) + [x, y] = meshgrid (x, y); + else + error ("plot3: [length(X), length(Y)] must match size (Z)"); + endif + endif + + if (! size_equal (x, y, z)) + error ("plot3: X, Y, and Z must have the same shape"); + elseif (ndims (x) > 2) + error ("plot3: X, Y, and Z must not have more than two dimensions"); + endif + + options = __default_plot_options__ (); + for i = 1 : columns (x) + linestyle = options.linestyle; + marker = options.marker; + if (isempty (marker) && isempty (linestyle)) + [linestyle, marker] = __next_line_style__ (); + endif + color = options.color; + if (isempty (color)) + color = __next_line_color__ (); + endif + + htmp(++idx) = line (hax, x(:, i), y(:, i), z(:, i), + "color", color, "linestyle", linestyle, + "marker", marker, properties{:}); + key = options.key; + if (! isempty (key)) + hlgnd = [hlgnd, htmp(idx)]; + tlgnd = {tlgnd{:}, key}; + endif + endfor + + x = new; + y_set = 0; + z_set = 0; + fmt_set = 0; + properties = {}; + endif + + endwhile if (property_set) - properties = [properties, new_cell]; - property_set = 0; - continue; + error ("plot3: properties must appear followed by a value"); endif - if (ischar (new)) - if (! z_set) - if (! y_set) - if (! x_set) - error ("plot3: needs x, [ y, [ z ] ]"); - else - z = imag (x); - y = real (x); - y_set = 1; - z_set = 1; - if (rows (x) > 1) - x = repmat ((1:rows (x))', 1, columns (x)); - else - x = 1:columns (x); - endif - endif - else + ## Handle last plot. + + if (x_set) + if (y_set) + if (! z_set) z = imag (y); y = real (y); z_set = 1; endif - endif - - if (! fmt_set) - [options, valid] = __pltopt__ ("plot3", new, false); - if (! valid) - properties = [properties, new_cell]; - property_set = 1; - continue; + else + y = real (x); + z = imag (x); + y_set = 1; + z_set = 1; + if (rows (x) > 1) + x = repmat ((1:rows (x))', 1, columns (x)); else - fmt_set = 1; - while (arg < nargin && ischar (varargin{arg+1})) - if (nargin - arg < 2) - error ("plot3: properties must appear followed by a value"); - endif - properties = [properties, varargin(arg+1:arg+2)]; - arg += 2; - endwhile + x = 1:columns (x); endif - else - properties = [properties, new_cell]; - property_set = 1; - continue; endif if (isvector (x) && isvector (y)) @@ -164,176 +316,56 @@ elseif (length (x) == rows (z) && length (y) == columns (z)) [x, y] = meshgrid (x, y); else - error ("plot3: [length(x), length(y)] must match size (z)"); + error ("plot3: [length(X), length(Y)] must match size (Z)"); endif endif if (! size_equal (x, y, z)) - error ("plot3: x, y, and z must have the same shape"); + error ("plot3: X, Y, and Z must have the same shape"); elseif (ndims (x) > 2) - error ("plot3: x, y, and z must not have more than two dimensions"); + error ("plot3: X, Y, and Z must not have more than two dimensions"); endif + options = __default_plot_options__ (); + for i = 1 : columns (x) linestyle = options.linestyle; marker = options.marker; if (isempty (marker) && isempty (linestyle)) - [linestyle, marker] = __next_line_style__ (); - endif - color = options.color; - if (isempty (color)) - color = __next_line_color__ (); - endif - - tmp(++idx) = line (x(:, i), y(:, i), z(:, i), - "color", color, "linestyle", linestyle, - "marker", marker, properties{:}); - key = options.key; - if (! isempty (key)) - hlgnd = [hlgnd, tmp(idx)]; - tlgnd = {tlgnd{:}, key}; - endif - endfor - - x_set = 0; - y_set = 0; - z_set = 0; - fmt_set = 0; - properties = {}; - elseif (! x_set) - x = new; - x_set = 1; - elseif (! y_set) - y = new; - y_set = 1; - elseif (! z_set) - z = new; - z_set = 1; - else - if (isvector (x) && isvector (y)) - if (isvector (z)) - x = x(:); - y = y(:); - z = z(:); - elseif (length (x) == rows (z) && length (y) == columns (z)) - [x, y] = meshgrid (x, y); - else - error ("plot3: [length(x), length(y)] must match size (z)"); - endif - endif - - if (! size_equal (x, y, z)) - error ("plot3: x, y, and z must have the same shape"); - elseif (ndims (x) > 2) - error ("plot3: x, y, and z must not have more than two dimensions"); - endif - - options = __default_plot_options__ (); - for i = 1 : columns (x) - linestyle = options.linestyle; - marker = options.marker; - if (isempty (marker) && isempty (linestyle)) - [linestyle, marker] = __next_line_style__ (); + [linestyle, marker] = __next_line_style__ (); endif color = options.color; if (isempty (color)) color = __next_line_color__ (); endif - tmp(++idx) = line (x(:, i), y(:, i), z(:, i), - "color", color, "linestyle", linestyle, - "marker", marker, properties{:}); + htmp(++idx) = line (hax, x(:, i), y(:, i), z(:, i), + "color", color, "linestyle", linestyle, + "marker", marker, properties{:}); key = options.key; if (! isempty (key)) - hlgnd = [hlgnd, tmp(idx)]; + hlgnd = [hlgnd, htmp(idx)]; tlgnd = {tlgnd{:}, key}; endif endfor - - x = new; - y_set = 0; - z_set = 0; - fmt_set = 0; - properties = {}; endif - endwhile - - if (property_set) - error ("plot3: properties must appear followed by a value"); - endif - - ## Handle last plot. - - if (x_set) - if (y_set) - if (! z_set) - z = imag (y); - y = real (y); - z_set = 1; - endif - else - z = imag (x); - y = real (x); - y_set = 1; - z_set = 1; - if (rows (x) > 1) - x = repmat ((1:rows (x))', 1, columns (x)); - else - x = 1:columns (x); - endif + if (! isempty (hlgnd)) + legend (hax, hlgnd, tlgnd); endif - if (isvector (x) && isvector (y)) - if (isvector (z)) - x = x(:); - y = y(:); - z = z(:); - elseif (length (x) == rows (z) && length (y) == columns (z)) - [x, y] = meshgrid (x, y); - else - error ("plot3: [length(x), length(y)] must match size (z)"); - endif - endif - - if (! size_equal (x, y, z)) - error ("plot3: x, y, and z must have the same shape"); - elseif (ndims (x) > 2) - error ("plot3: x, y, and z must not have more than two dimensions"); + if (! ishold ()) + set (hax, "view", [-37.5, 30]); endif - options = __default_plot_options__ (); - - for i = 1 : columns (x) - linestyle = options.linestyle; - marker = options.marker; - if (isempty (marker) && isempty (linestyle)) - [linestyle, marker] = __next_line_style__ (); - endif - color = options.color; - if (isempty (color)) - color = __next_line_color__ (); - endif - - tmp(++idx) = line (x(:, i), y(:, i), z(:, i), - "color", color, "linestyle", linestyle, - "marker", marker, properties{:}); - key = options.key; - if (! isempty (key)) - hlgnd = [hlgnd, tmp(idx)]; - tlgnd = {tlgnd{:}, key}; - endif - endfor - endif - - if (!isempty (hlgnd)) - legend (gca (), hlgnd, tlgnd); - endif - - set (gca (), "view", [-37.5, 30]); + unwind_protect_cleanup + if (! isempty (oldfig)) + set (0, "currentfigure", oldfig); + endif + end_unwind_protect if (nargout > 0 && idx > 0) - retval = tmp; + retval = htmp; endif endfunction @@ -343,5 +375,9 @@ %! clf; %! z = [0:0.05:5]; %! plot3 (cos (2*pi*z), sin (2*pi*z), z, ';helix;'); + +%!demo +%! clf; +%! z = [0:0.05:5]; %! plot3 (z, exp (2i*pi*z), ';complex sinusoid;');