]> Creatis software - CreaPhase.git/blob - octave_packages/m/plot/plot3.m
d259118b286db53a4c06539c548e894c73d5c860
[CreaPhase.git] / octave_packages / m / plot / plot3.m
1 ## Copyright (C) 1996-2012 John W. Eaton
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 ## -*- texinfo -*-
20 ## @deftypefn {Function File} {} plot3 (@var{args})
21 ## Produce three-dimensional plots.  Many different combinations of
22 ## arguments are possible.  The simplest form is
23 ##
24 ## @example
25 ## plot3 (@var{x}, @var{y}, @var{z})
26 ## @end example
27 ##
28 ## @noindent
29 ## in which the arguments are taken to be the vertices of the points to
30 ## be plotted in three dimensions.  If all arguments are vectors of the
31 ## same length, then a single continuous line is drawn.  If all arguments
32 ## are matrices, then each column of the matrices is treated as a
33 ## separate line.  No attempt is made to transpose the arguments to make
34 ## the number of rows match.
35 ##
36 ## If only two arguments are given, as
37 ##
38 ## @example
39 ## plot3 (@var{x}, @var{c})
40 ## @end example
41 ##
42 ## @noindent
43 ## the real and imaginary parts of the second argument are used
44 ## as the @var{y} and @var{z} coordinates, respectively.
45 ##
46 ## If only one argument is given, as
47 ##
48 ## @example
49 ## plot3 (@var{c})
50 ## @end example
51 ##
52 ## @noindent
53 ## the real and imaginary parts of the argument are used as the @var{y}
54 ## and @var{z} values, and they are plotted versus their index.
55 ##
56 ## Arguments may also be given in groups of three as
57 ##
58 ## @example
59 ## plot3 (@var{x1}, @var{y1}, @var{z1}, @var{x2}, @var{y2}, @var{z2}, @dots{})
60 ## @end example
61 ##
62 ## @noindent
63 ## in which each set of three arguments is treated as a separate line or
64 ## set of lines in three dimensions.
65 ##
66 ## To plot multiple one- or two-argument groups, separate each group
67 ## with an empty format string, as
68 ##
69 ## @example
70 ## plot3 (@var{x1}, @var{c1}, "", @var{c2}, "", @dots{})
71 ## @end example
72 ##
73 ## An example of the use of @code{plot3} is
74 ##
75 ## @example
76 ## @group
77 ## z = [0:0.05:5];
78 ## plot3 (cos (2*pi*z), sin (2*pi*z), z, ";helix;");
79 ## plot3 (z, exp (2i*pi*z), ";complex sinusoid;");
80 ## @end group
81 ## @end example
82 ## @seealso{plot, xlabel, ylabel, zlabel, title, print}
83 ## @end deftypefn
84
85 ## Author: Paul Kienzle
86 ##         (modified from __plt__.m)
87
88 function retval = plot3 (varargin)
89
90   newplot ();
91
92   x_set = 0;
93   y_set = 0;
94   z_set = 0;
95   property_set = 0;
96   fmt_set = 0;
97   properties = {};
98   tlgnd = {};
99   hlgnd = [];
100   idx = 0;
101
102   ## Gather arguments, decode format, and plot lines.
103   arg = 0;
104   while (arg++ < nargin)
105     new = varargin{arg};
106     new_cell = varargin(arg);
107
108     if (property_set)
109       properties = [properties, new_cell];
110       property_set = 0;
111       continue;
112     endif
113
114     if (ischar (new))
115       if (! z_set)
116         if (! y_set)
117           if (! x_set)
118             error ("plot3: needs x, [ y, [ z ] ]");
119           else
120             z = imag (x);
121             y = real (x);
122             y_set = 1;
123             z_set = 1;
124             if (rows(x) > 1)
125               x = repmat ((1:rows(x))', 1, columns(x));
126             else
127               x = 1:columns(x);
128             endif
129           endif
130         else
131           z = imag (y);
132           y = real (y);
133           z_set = 1;
134         endif
135       endif
136
137       if (! fmt_set)
138         [options, valid] = __pltopt__ ("plot3", new, false);
139         if (! valid)
140           properties = [properties, new_cell];
141           property_set = 1;
142           continue;
143         else
144           fmt_set = 1;
145           while (arg < nargin && ischar (varargin{arg+1}))
146             if (nargin - arg < 2)
147               error ("plot3: properties must appear followed by a value");
148             endif
149             properties = [properties, varargin(arg+1:arg+2)];
150             arg += 2;
151           endwhile
152         endif
153       else
154         properties = [properties, new_cell];
155         property_set = 1;
156         continue;
157       endif
158
159       if (isvector (x) && isvector (y))
160         if (isvector (z))
161           x = x(:);
162           y = y(:);
163           z = z(:);
164         elseif (length (x) == rows (z) && length (y) == columns (z))
165           [x, y] = meshgrid (x, y);
166         else
167           error ("plot3: [length(x), length(y)] must match size(z)");
168         endif
169       endif
170
171       if (! size_equal (x, y, z))
172         error ("plot3: x, y, and z must have the same shape");
173       elseif (ndims (x) > 2)
174         error ("plot3: x, y, and z must not have more than two dimensions");
175       endif
176
177       for i = 1 : columns (x)
178         linestyle = options.linestyle;
179         marker = options.marker;
180         if (isempty (marker) && isempty (linestyle))
181            [linestyle, marker] = __next_line_style__ ();
182         endif
183         color = options.color;
184         if (isempty (color))
185           color = __next_line_color__ ();
186         endif
187
188         tmp(++idx) = line (x(:, i), y(:, i), z(:, i),
189                            "color", color, "linestyle", linestyle,
190                            "marker", marker, properties{:});
191         key = options.key;
192         if (! isempty (key))
193           hlgnd = [hlgnd, tmp(idx)];
194           tlgnd = {tlgnd{:}, key};
195         endif
196       endfor
197
198       x_set = 0;
199       y_set = 0;
200       z_set = 0;
201       fmt_set = 0;
202       properties = {};
203     elseif (! x_set)
204       x = new;
205       x_set = 1;
206     elseif (! y_set)
207       y = new;
208       y_set = 1;
209     elseif (! z_set)
210       z = new;
211       z_set = 1;
212     else
213       if (isvector (x) && isvector (y))
214         if (isvector (z))
215           x = x(:);
216           y = y(:);
217           z = z(:);
218         elseif (length (x) == rows (z) && length (y) == columns (z))
219           [x, y] = meshgrid (x, y);
220         else
221           error ("plot3: [length(x), length(y)] must match size(z)");
222         endif
223       endif
224
225       if (! size_equal (x, y, z))
226         error ("plot3: x, y, and z must have the same shape");
227       elseif (ndims (x) > 2)
228         error ("plot3: x, y, and z must not have more than two dimensions");
229       endif
230
231       options =  __default_plot_options__ ();
232       for i = 1 : columns (x)
233         linestyle = options.linestyle;
234         marker = options.marker;
235         if (isempty (marker) && isempty (linestyle))
236            [linestyle, marker] = __next_line_style__ ();
237         endif
238         color = options.color;
239         if (isempty (color))
240           color = __next_line_color__ ();
241         endif
242
243         tmp(++idx) = line (x(:, i), y(:, i), z(:, i),
244                            "color", color, "linestyle", linestyle,
245                            "marker", marker, properties{:});
246         key = options.key;
247         if (! isempty (key))
248           hlgnd = [hlgnd, tmp(idx)];
249           tlgnd = {tlgnd{:}, key};
250         endif
251       endfor
252
253       x = new;
254       y_set = 0;
255       z_set = 0;
256       fmt_set = 0;
257       properties = {};
258     endif
259
260   endwhile
261
262   if (property_set)
263     error ("plot3: properties must appear followed by a value");
264   endif
265
266   ## Handle last plot.
267
268   if (x_set)
269     if (y_set)
270       if (! z_set)
271         z = imag (y);
272         y = real (y);
273         z_set = 1;
274       endif
275     else
276       z = imag (x);
277       y = real (x);
278       y_set = 1;
279       z_set = 1;
280       if (rows (x) > 1)
281         x = repmat ((1:rows (x))', 1, columns(x));
282       else
283         x = 1:columns(x);
284       endif
285     endif
286
287     if (isvector (x) && isvector (y))
288       if (isvector (z))
289         x = x(:);
290         y = y(:);
291         z = z(:);
292       elseif (length (x) == rows (z) && length (y) == columns (z))
293         [x, y] = meshgrid (x, y);
294       else
295         error ("plot3: [length(x), length(y)] must match size(z)");
296       endif
297     endif
298
299     if (! size_equal (x, y, z))
300       error ("plot3: x, y, and z must have the same shape");
301     elseif (ndims (x) > 2)
302       error ("plot3: x, y, and z must not have more than two dimensions");
303     endif
304
305     options =  __default_plot_options__ ();
306
307     for i = 1 : columns (x)
308       linestyle = options.linestyle;
309       marker = options.marker;
310       if (isempty (marker) && isempty (linestyle))
311         [linestyle, marker] = __next_line_style__ ();
312       endif
313       color = options.color;
314       if (isempty (color))
315         color = __next_line_color__ ();
316       endif
317
318       tmp(++idx) = line (x(:, i), y(:, i), z(:, i),
319                          "color", color, "linestyle", linestyle,
320                          "marker", marker, properties{:});
321       key = options.key;
322       if (! isempty (key))
323         hlgnd = [hlgnd, tmp(idx)];
324         tlgnd = {tlgnd{:}, key};
325       endif
326     endfor
327   endif
328
329   if (!isempty (hlgnd))
330     legend (gca(), hlgnd, tlgnd);
331   endif
332
333   set (gca (), "view", [-37.5, 30]);
334
335   if (nargout > 0 && idx > 0)
336     retval = tmp;
337   endif
338
339 endfunction
340
341 %!demo
342 %! clf
343 %! z = [0:0.05:5];
344 %! plot3 (cos(2*pi*z), sin(2*pi*z), z, ";helix;");
345 %! plot3 (z, exp(2i*pi*z), ";complex sinusoid;");