changeset 7170:9f38c6293317

[project @ 2007-11-13 17:34:33 by jwe]
author jwe
date Tue, 13 Nov 2007 17:34:33 +0000
parents f83b2ca41b05
children 9bc096bc59d4
files scripts/ChangeLog scripts/plot/Makefile.in scripts/plot/__contour__.m scripts/plot/__go_draw_axes__.m scripts/plot/contour.m scripts/plot/meshc.m scripts/plot/surfc.m
diffstat 7 files changed, 252 insertions(+), 175 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/ChangeLog	Tue Nov 13 17:17:38 2007 +0000
+++ b/scripts/ChangeLog	Tue Nov 13 17:34:33 2007 +0000
@@ -1,4 +1,19 @@
-2007-11-13  David Bateman  <dbateman@free.fr>
+2007-11-12  David Bateman  <dbateman@free.fr>
+
+	* plot/contour.m: Allow handles to be passed and returned. Split
+	the countour function itself into __contour__.m to be shared with
+	surfc and meshc.
+	* plot/__contour__.m: New file
+	* plot/Makefile.in (SOURCES): Add it to the sources.
+	* plot/__go_draw_axes.m: For patch objects don't attempt to patch
+	the face or edge if the facecolor or edge color are marked as
+	"none". Allow the edgecolor to be determined by the cdata in the
+	same manner as the facecolor. Fail if facecolor is not "none" and
+	a 3-D plot is desired, rather than ignoring zdata. Make the
+	storage of 3D/4D data consistent between line, surface and patch 
+	objects.
+	* plot/meshc.m: Use new __contour__.m to plot the contours.
+	* plot/surfc.m: Use new __contour__.m to plot the contours.
 
 	* plot/__go_draw_axes__.m (get_fontname_and_size):
 	Handle fontweight and fontangle properties.
--- a/scripts/plot/Makefile.in	Tue Nov 13 17:17:38 2007 +0000
+++ b/scripts/plot/Makefile.in	Tue Nov 13 17:34:33 2007 +0000
@@ -38,6 +38,7 @@
   __axes_limits__.m \
   __axis_label__.m \
   __bar__.m \
+  __contour__.m \
   __default_plot_options__.m \
   __errcomm__.m \
   __errplot__.m \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/plot/__contour__.m	Tue Nov 13 17:34:33 2007 +0000
@@ -0,0 +1,52 @@
+## Copyright (C) 2007 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/>.
+
+## Undocumented internal function.
+
+function [c, h] = __contour__ (varargin)
+
+  ax = varargin {1};
+  z = varargin {2};
+
+  clim = get (ax, "clim");
+
+  [c, lev] = contourc (varargin{3:end});
+
+  ## Decode contourc output format.
+  i1 = 1;
+  h = [];
+  maxlev = max (lev);
+  minlev = min (lev);
+  while (i1 < length (c))
+    clev = c(1,i1);
+    clen = c(2,i1);
+
+    ii = i1+1:i1+clen;
+    lev = (clev - minlev) * (clim(2) - clim(1)) / (maxlev - minlev) + clim(1);
+
+    if (isnan (z))
+      h = [h; patch(ax, c(1,ii), c(2,ii), "facecolor", "none", 
+		    "edgecolor", "flat", "cdata", lev)];
+    else
+      h = [h; patch(ax, c(1,ii), c(2,ii), z*ones(size(ii)), "facecolor",
+		    "none", "edgecolor", "flat", "cdata", lev)];
+    endif
+    i1 += clen+1;
+  endwhile
+  
+endfunction
--- a/scripts/plot/__go_draw_axes__.m	Tue Nov 13 17:17:38 2007 +0000
+++ b/scripts/plot/__go_draw_axes__.m	Tue Nov 13 17:34:33 2007 +0000
@@ -434,17 +434,18 @@
 	  endif
 
        case "patch"
-	 if (! isempty (obj.zdata))
-           warning ("gnuplot (as of v4.2) supports only 2D patches, ignoring z values")
-	 endif
-	 nd = 2;
          cmap = parent_figure_obj.colormap;
          clim = axis_obj.clim;
 	 [nr, nc] = size (obj.xdata);
 
-	 for i = 1 : nc
+	 for i = 1:nc
 	   xcol = obj.xdata(:,i);
 	   ycol = obj.ydata(:,i);
+	   if (! isempty (obj.zdata))
+	     zcol = obj.zdata(:,i);
+	   else
+	     zcol = [];
+	   endif
 
 	   if (xautoscale)
              [xmin, xmax, xminp] = get_data_limits (xmin, xmax, xminp, xcol);
@@ -452,26 +453,115 @@
 	   if (yautoscale)
 	     [ymin, ymax, yminp] = get_data_limits (ymin, ymax, yminp, ycol);
 	   endif
+	   if (! isempty (obj.zdata) && ! strncmp(obj.edgecolor, "none", 4))
+	     if (zautoscale)
+	       [zmin, zmax, zminp] = get_data_limits (zmin, zmax, zminp, zcol);
+	     endif
+	   endif
 
 	   if (! isnan (xcol) && ! isnan (ycol))
 	     ## Is the patch closed or not
-	     data_idx++;
-	     is_image_data(data_idx) = false;
-	     parametric(data_idx) = false;
-	     have_cdata(data_idx) = false;
-	     if (i > 1 || isempty (obj.keylabel))
-	       titlespec{data_idx} = "title \"\"";
+	     if (! strncmp (obj.facecolor, "none", 4)) 
+	       if (! isempty (zcol))
+		 error ("gnuplot (as of v4.2) only supports 2D filled patches");
+	       else
+		 nd = 2;
+	       endif
+
+	       data_idx++;
+	       is_image_data(data_idx) = false;
+	       parametric(data_idx) = false;
+	       have_cdata(data_idx) = false;
+	       if (i > 1 || isempty (obj.keylabel))
+		 titlespec{data_idx} = "title \"\"";
+	       else
+		 tmp = undo_string_escapes (obj.keylabel);
+		 titlespec{data_idx} = strcat ("title \"", tmp, "\"");
+	       endif
+	       usingclause{data_idx} = "";
+               if (isfield (obj, "facecolor") && isfield (obj, "cdata"))
+		 if (strncmp (obj.facecolor, "flat", 4)
+		     || strncmp (obj.facecolor, "interp", 6))
+		   if (ndims (obj.cdata) == 2
+		       && ((nr > 3 && size (obj.cdata, 2) == nc)
+			   || (size (obj.cdata, 1) > 1
+			       && size (obj.cdata, 2) == nc)))
+		     ccol = obj.cdata (:, i);
+		   elseif (ndims (obj.cdata) == 3)
+		     ccol = permute (obj.cdata (:, i, :), [1, 3, 2]);
+		   else
+		     ccol = obj.cdata;
+		   endif
+		   if (strncmp (obj.facecolor, "flat", 4))
+		     if (numel(ccol) == 3)
+		       color = ccol;
+		     else
+		       r = 1 + round ((size (cmap, 1) - 1)
+				      * (ccol - clim(1))/(clim(2) - clim(1)));
+		       r = max (1, min (r, size (cmap, 1)));
+		       color = cmap(r, :);
+		     endif
+		   elseif (strncmp (obj.facecolor, "interp", 6))
+		     warning ("\"interp\" not supported, using 1st entry of cdata")
+		     r = 1 + round ((size (cmap, 1) - 1) * ccol(1));
+		     r = max (1, min (r, size (cmap, 1)));
+		     color = cmap(r,:);
+		   endif
+		 else
+		   color = obj.facecolor;
+		 endif
+               else
+		 color = [0, 1, 0];
+               endif
+
+	       if (have_newer_gnuplot)
+		 withclause{data_idx} ...
+		     = sprintf ("with filledcurve lc rgb \"#%02x%02x%02x\"",
+				round (255*color));
+	       else
+		 if (isequal (color, [0,0,0]))
+		   typ = -1;
+		 elseif (isequal (color, [1,0,0]))
+		   typ = 1;
+		 elseif (isequal (color, [0,1,0]))
+		   typ = 2;
+		 elseif (isequal (color, [0,0,1]))
+		   typ = 3;
+		 elseif (isequal (color, [1,0,1]))
+		   typ = 4;
+		 elseif (isequal (color, [0,1,1]))
+		   typ = 5;
+		 elseif (isequal (color, [1,1,1]))
+		   typ = -1;
+		 elseif (isequal (color, [1,1,0]))
+		   typ = 7;
+		 else
+		   typ = -1;
+		 endif
+		 withclause{data_idx} = sprintf ("with filledcurve lt %d", typ);
+	       endif
+	       data{data_idx} = [xcol, ycol]';
+	       usingclause{data_idx} = "using ($1):($2)";
+	     endif
+	   endif
+
+           ## patch outline
+	   if (! strncmp (obj.edgecolor, "none", 4))
+	     if (! isempty (zcol))
+	       nd = 3;
 	     else
-	       tmp = undo_string_escapes (obj.keylabel);
-	       titlespec{data_idx} = strcat ("title \"", tmp, "\"");
+	       nd = 2;
 	     endif
+
+	     data_idx++;
+             is_image_data(data_idx) = false;
+             parametric(data_idx) = false;
+	     have_cdata(data_idx) = false;
+             titlespec{data_idx} = "title \"\"";
 	     usingclause{data_idx} = "";
-             if (isfield (obj, "facecolor") && isfield (obj, "cdata"))
-               if (strncmp (obj.facecolor, "none", 4))
-		 color = [1, 1, 1];
-
-               elseif (strncmp (obj.facecolor, "flat", 4)
-		       || strncmp (obj.facecolor, "interp", 6))
+             if (isfield (obj, "edgecolor") && isfield (obj, "cdata"))
+	       if (strncmp (obj.edgecolor, "flat", 4)
+		   || strncmp (obj.edgecolor, "interp", 6))
 		 if (ndims (obj.cdata) == 2
 		     && ((nr > 3 && size (obj.cdata, 2) == nc)
 			 || (size (obj.cdata, 1) > 1
@@ -482,8 +572,8 @@
 		 else
 		   ccol = obj.cdata;
 		 endif
-		 if (strncmp (obj.facecolor, "flat", 4))
-		   if (numel(ccol) == 3)
+		 if (strncmp (obj.edgecolor, "flat", 4))
+		   if (numel (ccol) == 3)
 		     color = ccol;
 		   else
 		     r = 1 + round ((size (cmap, 1) - 1)
@@ -491,23 +581,22 @@
 		     r = max (1, min (r, size (cmap, 1)));
 		     color = cmap(r, :);
 		   endif
-		 elseif (strncmp (obj.facecolor, "interp", 6))
+		 elseif (strncmp (obj.edgecolor, "interp", 6))
 		   warning ("\"interp\" not supported, using 1st entry of cdata")
 		   r = 1 + round ((size (cmap, 1) - 1) * ccol(1));
 		   r = max (1, min (r, size (cmap, 1)));
 		   color = cmap(r,:);
 		 endif
-	       else
-		 color = obj.facecolor;
 	       endif
+             elseif (isfield (obj, "edgecolor") && isnumeric (obj.edgecolor))
+	       color = obj.edgecolor;
              else
-	       color = [0, 1, 0];
+               color = [0, 0, 0];
              endif
-
 	     if (have_newer_gnuplot)
 	       withclause{data_idx} ...
-		 = sprintf ("with filledcurve lc rgb \"#%02x%02x%02x\"",
-			    round (255*color));
+		   = sprintf ("with lines lc rgb \"#%02x%02x%02x\"",
+			      round (255*color));
 	     else
 	       if (isequal (color, [0,0,0]))
 		 typ = -1;
@@ -528,67 +617,26 @@
 	       else
 		 typ = -1;
 	       endif
-	       withclause{data_idx} = sprintf ("with filledcurve lt %d", typ);
+	       withclause{data_idx} = sprintf ("with lines lt %d", typ);
 	     endif
-	     data{data_idx} = [xcol, ycol]';
-	     usingclause{data_idx} = "using ($1):($2)";
-	   endif
 
-           ## patch outline
-	   data_idx++;
-           is_image_data(data_idx) = false;
-           parametric(data_idx) = false;
-	   have_cdata(data_idx) = false;
-           titlespec{data_idx} = "title \"\"";
-	   usingclause{data_idx} = "";
-           if (isfield (obj, "edgecolor"))
-             if (strncmp (obj.edgecolor, "none", 4))
-               color = [1, 1, 1];
-             elseif (strncmp (obj.edgecolor, "flat", 4))
-               warning ("\"flat\" for edgecolor not supported");
-               color = [0, 0, 0];
-             elseif (strncmp (obj.edgecolor, "interp", 6))
-               warning ("\"interp\" for edgecolor not supported");
-               color = [0, 0, 0];
-             else
-	       color = obj.edgecolor;
-             endif
-           else
-             color = [0, 0, 0];
-           endif
-	   if (have_newer_gnuplot)
-	     withclause{data_idx} ...
-	       = sprintf ("with lines lc rgb \"#%02x%02x%02x\"",
-			  round (255*color));
-	   else
-	     if (isequal (color, [0,0,0]))
-	       typ = -1;
-	     elseif (isequal (color, [1,0,0]))
-	       typ = 1;
-	     elseif (isequal (color, [0,1,0]))
-	       typ = 2;
-	     elseif (isequal (color, [0,0,1]))
-	       typ = 3;
-	     elseif (isequal (color, [1,0,1]))
-	       typ = 4;
-	     elseif (isequal (color, [0,1,1]))
-	       typ = 5;
-	     elseif (isequal (color, [1,1,1]))
-	       typ = -1;
-	     elseif (isequal (color, [1,1,0]))
-	       typ = 7;
+	     if (! isempty (zcol))
+	       if (! isnan (xcol) && ! isnan (ycol) && ! isnan (zcol))
+		 data{data_idx} = [[xcol; xcol(1)], [ycol; ycol(1)], ...
+				   [zcol; zcol(1)]]';
+	       else
+		 data{data_idx} = [xcol, ycol, zcol]';
+	       endif
+	       usingclause{data_idx} = "using ($1):($2):($3)";
 	     else
-	       typ = -1;
+	       if (! isnan (xcol) && ! isnan (ycol))
+		 data{data_idx} = [[xcol; xcol(1)], [ycol; ycol(1)]]';
+	       else
+		 data{data_idx} = [xcol, ycol]';
+	       endif
+	       usingclause{data_idx} = "using ($1):($2)";
 	     endif
-	     withclause{data_idx} = sprintf ("with lines lt %d", typ);
 	   endif
-
-	   if (!isnan (xcol) && ! isnan (ycol))
-	     data{data_idx} = [[xcol; xcol(1)], [ycol; ycol(1)]]';
-	   else
-	     data{data_idx} = [xcol, ycol]';
-	   endif
-	   usingclause{data_idx} = "using ($1):($2)";
 	 endfor
 
 	case "surface"
@@ -599,7 +647,8 @@
 	    is_image_data(data_idx) = false;
 	    parametric(data_idx) = false;
 	    have_cdata(data_idx) = true;
-	    [style, typ, with] = do_linestyle_command (obj, data_idx, plot_stream);
+	    [style, typ, with] = do_linestyle_command (obj, data_idx,
+						       plot_stream);
 	    if (isempty (obj.keylabel))
 	      titlespec{data_idx} = "title \"\"";
 	    else
@@ -672,7 +721,7 @@
 	        zz(:,kk+3) = cdat(:,k);
 	        k++;
 	      endfor
-	      data{data_idx} = zz;
+	      data{data_idx} = zz.';
 	    endif
 	    usingclause{data_idx} = "using ($1):($2):($3):($4)";
 	    withclause{data_idx} = "with line palette";
@@ -1294,15 +1343,15 @@
     if (parametric)
       fprintf (plot_stream, "%.15g %.15g %.15g\n", data);
     else
-      nc = columns (data);
+      nr = rows (data);
       if (cdata)
-	for j = 1:4:nc
-	  fprintf (plot_stream, "%.15g %.15g %.15g %.15g\n", data(:,j:j+3)');
+	for j = 1:4:nr
+	  fprintf (plot_stream, "%.15g %.15g %.15g %.15g\n", data(j:j+3,:));
 	  fputs (plot_stream, "\n");
 	endfor
       else
-	for j = 1:3:nc
-	  fprintf (plot_stream, "%.15g %.15g %.15g\n", data(:,j:j+2)');
+	for j = 1:3:nr
+	  fprintf (plot_stream, "%.15g %.15g %.15g\n", data(j:j+2,:));
 	  fputs (plot_stream, "\n");
 	endfor
       endif
--- a/scripts/plot/contour.m	Tue Nov 13 17:17:38 2007 +0000
+++ b/scripts/plot/contour.m	Tue Nov 13 17:34:33 2007 +0000
@@ -22,6 +22,8 @@
 ## @deftypefnx {Function File} {@var{c} =} contour (@var{z}, @var{vn})
 ## @deftypefnx {Function File} {@var{c} =} contour (@var{x}, @var{y}, @var{z})
 ## @deftypefnx {Function File} {@var{c} =} contour (@var{x}, @var{y}, @var{z}, @var{vn})
+## @deftypefnx {Function File} {@var{c} =} contour (@var{h}, @dots{})
+## @deftypefnx {Function File} {[@var{c}, @var{h}] =} contour (@dots{})
 ## Plot level curves (contour lines) of the matrix @var{z}, using the
 ## contour matrix @var{c} computed by @code{contourc} from the same
 ## arguments; see the latter for their interpretation.  The set of
@@ -36,42 +38,38 @@
 ##
 ## @end group
 ## @end example
-## @seealso{contourc, line, plot}
+##
+## The optional input and output argument @var{h} allows an axis handle to 
+## be passed to @code{contour} and the handles to the contour objects to be
+## returned.
+## @seealso{contourc, patch, plot}
 ## @end deftypefn
 
 ## Author: shaia
 
-function retval = contour (varargin)
-
-  [c, lev] = contourc (varargin{:});
-
-  cmap = get (gcf(), "colormap");
-  
-  levx = linspace (min (lev), max (lev), size (cmap, 1));
-
-  newplot ();
-
-  ## Decode contourc output format.
-  i1 = 1;
-  while (i1 < length (c))
+function [c, h] = contour (varargin)
 
-    clev = c(1,i1);
-    clen = c(2,i1);
-
-    ccr = interp1 (levx, cmap(:,1), clev);
-    ccg = interp1 (levx, cmap(:,2), clev);
-    ccb = interp1 (levx, cmap(:,3), clev);
+  if (isscalar (varargin{1}) && ishandle (varargin{1}))
+    h = varargin{1};
+    if (! strcmp (get (h, "type"), "axes"))
+      error ("contour: expecting first argument to be an axes object");
+    endif
+    oldh = gca ();
+    unwind_protect
+      axes (h);
+      newplot ();
+      [ctmp, htmp] = __contour__ (h, varargin{2:end});
+    unwind_protect_cleanup
+      axes (oldh);
+    end_unwind_protect
+  else
+    newplot ();
+    [ctmp, htmp] = __contour__ (gca (), NaN, varargin{:});
+  endif
 
-    ii = i1+1:i1+clen;
-    line (c(1,ii), c(2,ii), "color", [ccr, ccg, ccb]);
-
-    i1 += c(2,i1)+1;
-  endwhile
-  
   if (nargout > 0)
-    retval = c;
+    c = ctmp;
+    h = htmp
   endif
 
 endfunction
-
-
--- a/scripts/plot/meshc.m	Tue Nov 13 17:17:38 2007 +0000
+++ b/scripts/plot/meshc.m	Tue Nov 13 17:34:33 2007 +0000
@@ -42,37 +42,17 @@
     set (ax, "view", [-37.5, 30]);
   endif
 
-  hold ("on");
-
-  [c, lev] = contourc (varargin{:});
-
-  cmap = get (gcf (), "colormap");
-  
-  levx = linspace (min (lev), max (lev), size (cmap, 1));
-
-  drawnow();
-  ax = axis();
-  zmin = 2 * ax(5) - ax(6);
-
-  ## Decode contourc output format.
-  i1 = 1;
-  while (i1 < length (c))
+  if (nargin == 1)
+    z = varargin {1};
+  else
+    z = varargin {3};
+  endif
+  zmin = 2 * (min(z(:)) - max(z(:)));
 
-    clev = c(1,i1);
-    clen = c(2,i1);
-
-    ccr = interp1 (levx, cmap(:,1), clev);
-    ccg = interp1 (levx, cmap(:,2), clev);
-    ccb = interp1 (levx, cmap(:,3), clev);
+  [c, tmp2] = __contour__ (ax, zmin, varargin{:});
 
-    ii = i1+1:i1+clen;
-    line (c(1,ii), c(2,ii), zmin * ones (size (ii)), "color",
-	  [ccr, ccg, ccb]);
+  tmp = [tmp; tmp2];
 
-    i1 += c(2,i1)+1;
-
-  endwhile
-  
   if (nargout > 0)
     h = tmp;
   endif
--- a/scripts/plot/surfc.m	Tue Nov 13 17:17:38 2007 +0000
+++ b/scripts/plot/surfc.m	Tue Nov 13 17:34:33 2007 +0000
@@ -41,35 +41,17 @@
     set (ax, "view", [-37.5, 30]);
   endif
 
-  hold ("on");
-
-  [c, lev] = contourc (varargin{:});
-
-  cmap = get (gcf(), "colormap");
-  
-  levx = linspace (min (lev), max (lev), size (cmap, 1));
-
-  drawnow ();
-  ax = axis ();
-  zmin = 2 * ax(5) - ax(6);
+  if (nargin == 1)
+    z = varargin {1};
+  else
+    z = varargin {3};
+  endif
+  zmin = 2 * (min(z(:)) - max(z(:)));
 
-  ## decode contourc output format
-  i1 = 1;
-  while (i1 < length (c))
-
-    clev = c(1,i1);
-    clen = c(2,i1);
+  [c, tmp2] = __contour__ (ax, zmin, varargin{:});
 
-    ccr = interp1 (levx, cmap(:,1), clev);
-    ccg = interp1 (levx, cmap(:,2), clev);
-    ccb = interp1 (levx, cmap(:,3), clev);
+  tmp = [tmp; tmp2];
 
-    ii = i1+1:i1+clen;
-    line (c(1,ii), c(2,ii), zmin*ones(size(ii)), "color", [ccr, ccg, ccb]);
-
-    i1 += c(2,i1)+1;
-  endwhile
-  
   if (nargout > 0)
     h = tmp;
   endif