# HG changeset patch # User jwe # Date 1194975273 0 # Node ID 9f38c6293317b40b46a15a99470f3f2b2d77da1d # Parent f83b2ca41b056ca332131005a61f32058aa8f946 [project @ 2007-11-13 17:34:33 by jwe] diff --git a/scripts/ChangeLog b/scripts/ChangeLog --- a/scripts/ChangeLog +++ b/scripts/ChangeLog @@ -1,4 +1,19 @@ -2007-11-13 David Bateman +2007-11-12 David Bateman + + * 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. diff --git a/scripts/plot/Makefile.in b/scripts/plot/Makefile.in --- a/scripts/plot/Makefile.in +++ b/scripts/plot/Makefile.in @@ -38,6 +38,7 @@ __axes_limits__.m \ __axis_label__.m \ __bar__.m \ + __contour__.m \ __default_plot_options__.m \ __errcomm__.m \ __errplot__.m \ diff --git a/scripts/plot/__contour__.m b/scripts/plot/__contour__.m new file mode 100644 --- /dev/null +++ b/scripts/plot/__contour__.m @@ -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 +## . + +## 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 diff --git a/scripts/plot/__go_draw_axes__.m b/scripts/plot/__go_draw_axes__.m --- a/scripts/plot/__go_draw_axes__.m +++ b/scripts/plot/__go_draw_axes__.m @@ -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 diff --git a/scripts/plot/contour.m b/scripts/plot/contour.m --- a/scripts/plot/contour.m +++ b/scripts/plot/contour.m @@ -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 - - diff --git a/scripts/plot/meshc.m b/scripts/plot/meshc.m --- a/scripts/plot/meshc.m +++ b/scripts/plot/meshc.m @@ -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 diff --git a/scripts/plot/surfc.m b/scripts/plot/surfc.m --- a/scripts/plot/surfc.m +++ b/scripts/plot/surfc.m @@ -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