changeset 7109:5436efbf35e3

[project @ 2007-11-06 22:16:25 by jwe]
author jwe
date Tue, 06 Nov 2007 22:16:25 +0000
parents 60a1165732f9
children 0e63f1126f01
files scripts/ChangeLog scripts/plot/__go_draw_axes__.m scripts/plot/mesh.m scripts/plot/pcolor.m scripts/plot/shading.m scripts/plot/surf.m scripts/plot/surface.m
diffstat 7 files changed, 446 insertions(+), 133 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/ChangeLog	Tue Nov 06 22:06:27 2007 +0000
+++ b/scripts/ChangeLog	Tue Nov 06 22:16:25 2007 +0000
@@ -1,3 +1,16 @@
+2007-11-06  John W. Eaton  <jwe@octave.org>
+
+2007-11-06  Kai Habel  <kai.habel@gmx.de>
+
+	* plot/pcolor.m, plot/shading.m, plot/surf.m, plot/surface.m:
+	New files.
+	* plot/mesh.m: Call surface to do the real work.
+	* plot/__go_draw_axes__.m: Use pm3d mode to handle new surface
+	properties.
+
+	* image/colormap.m: Also return current colormap if nargout and
+	nargin are both 0.
+
 2007-11-05  Michael Goffioul  <michael.goffioul@gmail.com>
 
 	* startup/inputrc: Delete key bindings starting with \340 code.
--- a/scripts/plot/__go_draw_axes__.m	Tue Nov 06 22:06:27 2007 +0000
+++ b/scripts/plot/__go_draw_axes__.m	Tue Nov 06 22:16:25 2007 +0000
@@ -193,6 +193,7 @@
     xautoscale = strcmpi (axis_obj.xlimmode, "auto");
     yautoscale = strcmpi (axis_obj.ylimmode, "auto");
     zautoscale = strcmpi (axis_obj.zlimmode, "auto");
+    cautoscale = strcmpi (axis_obj.climmode, "auto");
 
     kids = axis_obj.children;
 
@@ -201,9 +202,9 @@
     data = cell ();
     is_image_data = [];
 
-    xminp = yminp = zminp = Inf;
-    xmax = ymax = zmax = -Inf;
-    xmin = ymin = zmin = Inf;
+    xminp = yminp = zminp = cminp = Inf;
+    xmax = ymax = zmax = cmax = -Inf;
+    xmin = ymin = zmin = cmin = Inf;
 
     [view_cmd, view_fcn, view_zoom] = image_viewer ();
     use_gnuplot_for_images = (ischar (view_fcn)
@@ -572,96 +573,149 @@
 	 endfor
 
 	case "surface"
-	  data_idx++;
-	  is_image_data(data_idx) = false;
-	  parametric(data_idx) = false;
-	  [style, typ, with] = do_linestyle_command (obj, data_idx, plot_stream);
-	  if (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 (have_newer_gnuplot || isnan (typ))
-	    withclause{data_idx} = sprintf ("with %s linestyle %d",
-					    style, data_idx);
-	  else
-	    withclause{data_idx} = sprintf ("with %s linetype %d %s",
-					    style, typ, with);
-	  endif
-	  nd = 3;
-	  xdat = obj.xdata;
-	  ydat = obj.ydata;
-	  zdat = obj.zdata;
-	  if (xautoscale)
-	    tx = xdat(:);
-	    [xmin, xmax, xminp] = get_data_limits (xmin, xmax, xminp, tx);
-	  endif
-	  if (yautoscale)
-	    ty = ydat(:);
-	    [ymin, ymax, yminp] = get_data_limits (ymin, ymax, yminp, ty);
-	  endif
-	  if (zautoscale)
-	    tz = zdat(:);
-	    [zmin, zmax, zminp] = get_data_limits (zmin, zmax, zminp, tz);
-	  endif
-	  err = false;
-	  if (isvector (xdat) && isvector (ydat) && ismatrix (zdat))
-	    if (rows (zdat) == length (ydat) && columns (zdat) == length (xdat))
-              [xdat, ydat] = meshgrid (xdat, ydat);
+	  nd = 4;
+          if !((strncmp(obj.edgecolor,"none",4)) && (strncmp(obj.facecolor,"none",4)))
+	    data_idx++;
+	    is_image_data(data_idx) = false;
+	    parametric(data_idx) = false;
+	    [style, typ, with] = do_linestyle_command (obj, data_idx, plot_stream);
+	    if (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 (have_newer_gnuplot || isnan (typ))
+	      withclause{data_idx} = sprintf ("with %s linestyle %d",
+		           		      style, data_idx);
 	    else
-              err = true;
+	      withclause{data_idx} = sprintf ("with %s linetype %d %s",
+		 			      style, typ, with);
+	    endif
+
+	    xdat = obj.xdata;
+	    ydat = obj.ydata;
+	    zdat = obj.zdata;
+	    cdat = obj.cdata;
+	  
+	    if (xautoscale)
+	      tx = xdat(:);
+	      [xmin, xmax, xminp] = get_data_limits (xmin, xmax, xminp, tx);
+	    endif
+	    if (yautoscale)
+	      ty = ydat(:);
+	      [ymin, ymax, yminp] = get_data_limits (ymin, ymax, yminp, ty);
+	    endif
+	    if (zautoscale)
+	      tz = zdat(:);
+	      [zmin, zmax, zminp] = get_data_limits (zmin, zmax, zminp, tz);
 	    endif
-	  elseif (ismatrix (xdat) && ismatrix (ydat) && ismatrix (zdat))
-	    if (! (size_equal (xdat, ydat) && size_equal (xdat, zdat)))
+	    if (cautoscale)
+	      tc = cdat(:);
+	      [cmin, cmax, cminp] = get_data_limits (cmin, cmax, cminp, tc);
+	    endif
+
+  	    err = false;
+            if (! size_equal(zdat, cdat))
               err = true;
+            endif
+	    if (isvector (xdat) && isvector (ydat) && ismatrix (zdat))
+	      if (rows (zdat) == length (ydat) && columns (zdat) == length (xdat))
+                [xdat, ydat] = meshgrid (xdat, ydat);
+	      else
+                err = true;
+	      endif
+	    elseif (ismatrix (xdat) && ismatrix (ydat) && ismatrix (zdat))
+	      if (! (size_equal (xdat, ydat) && size_equal (xdat, zdat)))
+                err = true;
+	      endif
+	    else
+	      err = true;
+	    endif
+	    if (err)
+	      error ("__go_draw_axes__: invalid grid data");
 	    endif
-	  else
-	    err = true;
-	  endif
-	  if (err)
-	    error ("__go_draw_axes__: invalid grid data");
-	  endif
-	  xlen = columns (zdat);
-	  ylen = rows (zdat);
-	  if (xlen == columns (xdat) && xlen == columns (ydat)
-	      && ylen == rows (xdat) && ylen == rows (ydat))
-	    len = 3 * xlen;
-	    zz = zeros (ylen, len);
-	    k = 1;
-	    for kk = 1:3:len
-	      zz(:,kk)   = xdat(:,k);
-	      zz(:,kk+1) = ydat(:,k);
-	      zz(:,kk+2) = zdat(:,k);
-	      k++;
-	    endfor
-	    data{data_idx} = zz;
+	    xlen = columns (zdat);
+	    ylen = rows (zdat);
+	    if (xlen == columns (xdat) && xlen == columns (ydat)
+	        && ylen == rows (xdat) && ylen == rows (ydat))
+	      len = 4 * xlen;
+	      zz = zeros (ylen, len);
+	      k = 1;
+	      for kk = 1:4:len
+	        zz(:,kk)   = xdat(:,k);
+	        zz(:,kk+1) = ydat(:,k);
+	        zz(:,kk+2) = zdat(:,k);
+	        zz(:,kk+3) = cdat(:,k);
+	        k++;
+	      endfor
+	      data{data_idx} = zz;
+	    endif
+	    usingclause{data_idx} = "using ($1):($2):($3):($4)";
+	    withclause{data_idx} = "with line palette";
+
+	    fputs (plot_stream, "unset parametric;\n");
+	    fputs (plot_stream, "set hidden3d;\n");
+	    fputs (plot_stream, "set style data lines;\n");
+	    fputs (plot_stream, "set surface;\n");
+	    fputs (plot_stream, "unset contour;\n");
+	    fprintf (plot_stream, "set cbrange [%g:%g];\n", cmin, cmax);
+
+	    if (have_newer_gnuplot)
+	      ## Interpolation does not work for flat surfaces (e.g. pcolor)
+              ## and color mapping --> currently set empty
+              interp_str = "";
+              surf_colormap = parent_figure_obj.colormap;
+              flat_interp_face = strncmp(obj.facecolor,"flat",4) || strncmp(obj.facecolor,"interp",6);
+              flat_interp_edge = strncmp(obj.edgecolor,"flat",4) || strncmp(obj.edgecolor,"interp",6);
+              palette_data = [];
+
+              if ((flat_interp_face) || 
+                  (flat_interp_edge && strncmp(obj.facecolor,"none",4)))
+                palette_data = [1:rows(surf_colormap); surf_colormap'];
+              endif 
+
+              if (isnumeric(obj.facecolor))
+                palette_data = [1:2; [obj.facecolor; obj.facecolor]'];
+              endif
+
+              if ((strncmp(obj.facecolor,"none",4) && isnumeric(obj.edgecolor)))
+                palette_data = [1:2; [obj.edgecolor; obj.edgecolor]'];
+              endif
+
+              if (strncmp(obj.facecolor,"none",4))
+              elseif (flat_interp_face && strncmp(obj.edgecolor,"flat",4))
+                fprintf (plot_stream, "set pm3d at s %s\n", interp_str);
+              else
+                if (strncmp(obj.edgecolor,"none",4))
+                  fprintf (plot_stream, "set pm3d at s %s\n", interp_str);
+                else
+                  edgecol = obj.edgecolor;
+                  if (ischar(obj.edgecolor))
+                    edgecol = [0 0 0];
+                  endif
+                  fprintf (plot_stream, "set pm3d at s hidden3d %d %s \n", data_idx, interp_str);
+                  fprintf (plot_stream, 
+                           "set style line %d linecolor rgb \"#%02x%02x%02x\" lw %f\n",
+                           data_idx, round (255*edgecol), obj.linewidth);
+                endif
+              endif
+
+              if (length(palette_data) > 0)
+                fprintf (plot_stream,
+	                 "set palette positive color model RGB maxcolors %i;\n",
+	                 columns(palette_data));
+	        fprintf (plot_stream,
+	                 "set palette file \"-\" binary record=%d using 1:2:3:4;\n",
+	                 columns(palette_data));
+	        fwrite (plot_stream, palette_data, "float32");
+              endif
+	    else
+	      fputs (plot_stream, "set palette defined (0 \"dark-blue\", 1 \"blue\", 2 \"cyan\", 3 \"yellow\", 4 \"red\" , 5 \"dark-red\");\n");
+	    endif
+	    fputs (plot_stream, "unset colorbox;\n");
 	  endif
-	  usingclause{data_idx} = "using ($1):($2):($3)";
-	  withclause{data_idx} = "with line palette";
-
-	  fputs (plot_stream, "unset parametric;\n");
-	  fputs (plot_stream, "set hidden3d;\n");
-	  fputs (plot_stream, "set style data lines;\n");
-	  fputs (plot_stream, "set surface;\n");
-	  fputs (plot_stream, "unset contour;\n");
-	  fprintf (plot_stream, "set cbrange [%g:%g];\n", zmin, zmax);
-
-	  if (have_newer_gnuplot)
-	    surf_colormap = parent_figure_obj.colormap;
-	    palette_size = rows (surf_colormap);
-	    fprintf (plot_stream,
-		     "set palette positive color model RGB maxcolors %i;\n",
-		     palette_size);
-	    fprintf (plot_stream,
-		     "set palette file \"-\" binary record=%d using 1:2:3:4;\n",
-		     palette_size);
-	    fwrite (plot_stream, [1:palette_size; surf_colormap'], "float32");
-	  else
-	    fputs (plot_stream, "set palette defined (0 \"dark-blue\", 1 \"blue\", 2 \"cyan\", 3 \"yellow\", 4 \"red\" , 5 \"dark-red\");\n");
-	  endif
-	  fputs (plot_stream, "unset colorbox;\n");
 
 	case "text"
 	  lpos = obj.position;
@@ -757,7 +811,7 @@
     endif
     fprintf (plot_stream, "set %srange [%.15e:%.15e] %s;\n", yaxisloc, ylim, ydir);
 
-    if (nd == 3)
+    if (nd == 3 || nd == 4)
       if (zautoscale && have_data)
 	zlim = get_axis_limits (zmin, zmax, zminp, zlogscale);
 	if (isempty (zlim))
@@ -774,15 +828,15 @@
       endif
       fprintf (plot_stream, "set zrange [%.15e:%.15e] %s;\n", zlim, zdir);
     endif
-
+		      
     if (strcmpi (axis_obj.box, "on"))
-      if (nd == 3)
+      if (nd == 3 || nd == 4)
 	fputs (plot_stream, "set border 4095;\n");
       else
 	fputs (plot_stream, "set border 431;\n");
       endif
     else
-      if (nd == 3)
+      if (nd == 3 || nd == 4)
 	fputs (plot_stream, "set border 895;\n");
       else
 	fputs (plot_stream, "set border 3;\n");
@@ -898,7 +952,7 @@
 
   else
     print_usage ();
-  endif    
+  endif
 
 endfunction
 
@@ -1154,7 +1208,7 @@
 	endif
       endfor
     endif
-  else
+  elseif (nd == 3)
     ## FIXME -- handle NaNs here too?
     if (parametric)
       fprintf (plot_stream, "%.15g %.15g %.15g\n", data);
@@ -1165,6 +1219,17 @@
 	fputs (plot_stream, "\n");
       endfor
     endif
+  elseif (nd == 4)
+    ## FIXME -- handle NaNs here too?
+    if (parametric)
+      fprintf (plot_stream, "%.15g %.15g %.15g\n", data);
+    else
+      nc = columns (data);
+      for j = 1:4:nc
+	fprintf (plot_stream, "%.15g %.15g %.15g %.15g\n", data(:,j:j+3)');
+	fputs (plot_stream, "\n");
+      endfor
+    endif
   endif
   fputs (plot_stream, "e\n");
 
--- a/scripts/plot/mesh.m	Tue Nov 06 22:06:27 2007 +0000
+++ b/scripts/plot/mesh.m	Tue Nov 06 22:16:25 2007 +0000
@@ -30,48 +30,15 @@
 
 ## Author: jwe
 
-function h = mesh (x, y, z)
+function h = mesh (varargin)
 
   newplot ();
 
-  if (nargin == 1)
-    z = x;
-    if (ismatrix (z))
-      [nr, nc] = size (z);
-      x = 1:nc;
-      y = (1:nr)';
-    else
-      error ("mesh: argument must be a matrix");
-    endif
-  elseif (nargin == 3)
-    if (isvector (x) && isvector (y) && ismatrix (z))
-      if (rows (z) == length (y) && columns (z) == length (x))
-        x = x(:)';
-        y = y(:);
-      else
-        msg = "mesh: rows (z) must be the same as length (y) and";
-        msg = sprintf ("%s\ncolumns (z) must be the same as length (x)", msg);
-        error (msg);
-      endif
-    elseif (ismatrix (x) && ismatrix (y) && ismatrix (z))
-      if (! (size_equal (x, y) && size_equal (x, z)))
-        error ("mesh: x, y, and z must have same dimensions");
-      endif
-    else
-      error ("mesh: x and y must be vectors and z must be a matrix");
-    endif
-  else
-    print_usage ();
-  endif
-
-  ## make a default line object, and make it the current axes for the
-  ## current figure.
-  ca = gca ();
-
-  tmp = __go_surface__ (ca, "xdata", x, "ydata", y, "zdata", z);
-
-  set (ca, "view", [-37.5, 30]);
-
+  tmp = surface (varargin{:});
+  ax = get(tmp, "parent");
+  set (tmp, "FaceColor", "none");
+  set (tmp, "EdgeColor", "flat");
+  set (ax, "view", [-37.5, 30]);
   if (nargout > 0)
     h = tmp;
   endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/plot/pcolor.m	Tue Nov 06 22:16:25 2007 +0000
@@ -0,0 +1,59 @@
+
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2002, 2004,
+##               2005, 2006, 2007 John W. Eaton
+##
+## 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} {} pcolor (@var{x}, @var{y}, @var{c})
+## @deftypefnx {Function File} {} pcolor (@var{c})
+## Density plot for given matrices @var{x}, and @var{y} from @code{meshgrid} and
+## a matrix @var{c} corresponding to the @var{x} and @var{y} coordinates of
+## the mesh.  If @var{x} and @var{y} are vectors, then a typical vertex
+## is (@var{x}(j), @var{y}(i), @var{c}(i,j)).  Thus, columns of @var{c}
+## correspond to different @var{x} values and rows of @var{c} correspond
+## to different @var{y} values.
+## @seealso{meshgrid, contour}
+## @end deftypefn
+
+## Author: jwe
+
+function h = pcolor (x,y,c)
+
+  newplot ();
+
+  if (nargin == 1)
+    C = x;
+    Z = zeros(size(C));
+    [nr, nc] = size(C);
+    [X, Y] = meshgrid(1:nr, 1:nc);
+  elseif (nargin == 3)
+    Z = zeros(size(C));
+  else
+    print_usage();
+  end;
+
+
+  tmp = surface (X,Y,Z,C);
+  ax = get(tmp, "parent");
+  set (tmp, "FaceColor", "flat");
+  set (ax, "view", [0, 90]);
+  if (nargout > 0)
+    h = tmp;
+  endif
+
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/plot/shading.m	Tue Nov 06 22:16:25 2007 +0000
@@ -0,0 +1,63 @@
+
+## Copyright (C) 2006,2007  Kai Habel
+##
+## 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 2, 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, write to the Free
+## Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+## 02110-1301, USA.
+
+## -*- texinfo -*-
+## @deftypefn {Function File}  shading (@var{type})
+## @deftypefnx {Function File}  shading (@var{ax}, ...)
+##
+## Sets the shading of surface or patch graphic objects. Valid arguments for
+## @var{type} are "flat", "interp", or "faceted".
+## If @var{ax} is given the shading is applied to axis @var{ax} instead of the 
+## current axis.
+##
+## @example
+## shading ("interp")
+## @end example
+##
+## @end deftypefn
+
+function shading(ax, mode)
+
+  if (nargin == 1)
+    mode = ax;
+    ax = gca();
+  end
+
+  if ((nargin !=1 ) && (nargin != 2))
+    print_usage();
+  end
+
+  obj = findobj(ax,"Type","patch");
+  obj = [obj; findobj(ax,"Type","surface")];
+
+  for n = 1 : length(obj)
+    h = obj(n); 
+    if strcmp(mode, "flat") 
+      set(h,"FaceColor","flat");
+      set(h,"EdgeColor","none");
+    elseif strcmp(mode,"interp")
+      set(h,"FaceColor","interp");
+      set(h,"EdgeColor","none");
+    elseif strcmp(mode,"faceted")
+      set(h,"FaceColor","flat");
+      set(h,"EdgeColor",[0 0 0]);
+    else
+      error("unknown argument")
+    endif
+  endfor
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/plot/surf.m	Tue Nov 06 22:16:25 2007 +0000
@@ -0,0 +1,46 @@
+
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2002, 2004,
+##               2005, 2006, 2007 John W. Eaton
+##
+## 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} {} surf (@var{x}, @var{y}, @var{z})
+## Plot a surface given matrices @var{x}, and @var{y} from @code{meshgrid} and
+## a matrix @var{z} corresponding to the @var{x} and @var{y} coordinates of
+## the mesh.  If @var{x} and @var{y} are vectors, then a typical vertex
+## is (@var{x}(j), @var{y}(i), @var{z}(i,j)).  Thus, columns of @var{z}
+## correspond to different @var{x} values and rows of @var{z} correspond
+## to different @var{y} values.
+## @seealso{mesh, surface}
+## @end deftypefn
+
+## Author: jwe
+
+function h = surf (varargin)
+
+  newplot ();
+
+  tmp = surface (varargin{:});
+  ax = get(tmp, "parent");
+  set (tmp, "FaceColor", "flat");
+  set (ax, "view", [-37.5, 30]);
+  if (nargout > 0)
+    h = tmp;
+  endif
+
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/plot/surface.m	Tue Nov 06 22:16:25 2007 +0000
@@ -0,0 +1,100 @@
+
+## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2002, 2004,
+##               2005, 2006, 2007 John W. Eaton
+##
+## 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} @var{h} = {} surface (@var{x}, @var{y}, @var{z}, @var{c})
+## @deftypefnx {Function File} @var{h} = {} surface (@var{x}, @var{y}, @var{z})
+## Plot a surface graphic object given matrices @var{x}, and @var{y} from @code{meshgrid} and
+## a matrix @var{z} corresponding to the @var{x} and @var{y} coordinates of
+## the surface.  If @var{x} and @var{y} are vectors, then a typical vertex
+## is (@var{x}(j), @var{y}(i), @var{z}(i,j)).  Thus, columns of @var{z}
+## correspond to different @var{x} values and rows of @var{z} correspond
+## to different @var{y} values.
+## @seealso{surf, mesh, patch, line}
+## @end deftypefn
+
+## Author: jwe
+
+function h = surface (x, y, z, c)
+
+  ax = gca();
+
+  if (nargin == 1)
+    c = z = x;
+    if (ismatrix (z))
+      [nr, nc] = size (z);
+      x = 1:nc;
+      y = (1:nr)';
+    else
+      error ("surface: argument must be a matrix");
+    endif
+  elseif (nargin == 3)
+    if (isvector (x) && isvector (y) && ismatrix (z))
+      if (rows (z) == length (y) && columns (z) == length (x))
+        x = x(:)';
+        y = y(:);
+      else
+        msg = "surface: rows (z) must be the same as length (y) and";
+        msg = sprintf ("%s\ncolumns (z) must be the same as length (x)", msg);
+        error (msg);
+      endif
+    elseif (ismatrix (x) && ismatrix (y) && ismatrix (z))
+      if (! (size_equal (x, y) && size_equal (x, z)))
+        error ("surface: x, y, and z must have same dimensions");
+      endif
+      c = z;
+    else
+      error ("surface: x and y must be vectors and z must be a matrix");
+    endif
+  elseif (nargin == 4)
+    if !(size_equal (z, c))
+      error ("surface: z and c must have same size");
+    endif
+    if (isvector (x) && isvector (y) && ismatrix (z))
+      if (rows (z) == length (y) && columns (z) == length (x))
+        x = x(:)';
+        y = y(:);
+      else
+        msg = "surface: rows (z) must be the same as length (y) and";
+        msg = sprintf ("%s\ncolumns (z) must be the same as length (x)", msg);
+        error (msg);
+      endif
+    elseif (ismatrix (x) && ismatrix (y) && ismatrix (z))
+      if (! (size_equal (x, y) && size_equal (x, z)))
+        error ("surface: x, y, and z must have same dimensions");
+      endif
+    else
+      error ("surface: x and y must be vectors and z must be a matrix");
+    endif
+  else
+    print_usage ();
+  endif
+
+  ## make a default surface object
+  tmp = __go_surface__ (ax, "xdata", x, "ydata", y, "zdata", z, "cdata", c);
+
+  set (ax, "view", [0, 90], "box", "off");
+  set (tmp, "FaceColor","flat");
+
+  if (nargout > 0)
+    h = tmp;
+  endif
+
+endfunction