Mercurial > hg > octave-lojdl
changeset 8070:3b53b25e2550
Add data sources and line series
author | David Bateman <dbateman@free.fr> |
---|---|
date | Thu, 28 Aug 2008 12:23:54 -0400 |
parents | c64c9581e9bf |
children | b6e85fb238c1 |
files | ChangeLog NEWS doc/ChangeLog doc/interpreter/plot.txi scripts/ChangeLog scripts/plot/Makefile.in scripts/plot/__add_datasource__.m scripts/plot/__add_line_series__.m scripts/plot/__area__.m scripts/plot/__bars__.m scripts/plot/__plt2mm__.m scripts/plot/__plt2mv__.m scripts/plot/__plt2ss__.m scripts/plot/__plt2sv__.m scripts/plot/__plt2vm__.m scripts/plot/__plt2vs__.m scripts/plot/__plt2vv__.m scripts/plot/__quiver__.m scripts/plot/__stem__.m scripts/plot/ishghandle.m scripts/plot/linkprop.m scripts/plot/plot3.m scripts/plot/refresh.m scripts/plot/refreshdata.m scripts/plot/stairs.m scripts/plot/stem.m src/ChangeLog src/graphics.h.in |
diffstat | 28 files changed, 700 insertions(+), 52 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2008-08-28 David Bateman <dbateman@free.fr> + + * NEWS: Update for some of the graphics changes + 2008-08-11 Jaroslav Hajek <highegg@gmail.com> * acx_blas_f77_func.m4, acx_lapack.m4: Update macros from
--- a/NEWS +++ b/NEWS @@ -3,6 +3,37 @@ ** Compatibility with Matlab graphics is much better now. + The hggroup object and associated listener callback functions have + been added allowing the inclusion of group objects. Data sources + have been added to these group objects such that + + x = 0:0.1:10; + y = sin (x); + plot (x, y, "ydatasource", "y"); + for i = 1 : 100 + pause(0.1) + y = sin (x + 0.1 * i); + refreshdata(); + endfor + + works as expected. + + TO BE WRITTEN (Shai / Micheal inputs please) + + ** Experimental OpenGL/FLTK based backend to replace gnuplot + + An experimental backend to replace the gnuplot backend has been + written based on FLTK. This backend is off by default. You can + switch to using this with the command + + backend ("fltk") + + for all future figures or for a particular figure with the command + + backend (h, "fltk") + + where "h" is a valid figure handle. + TO BE WRITTEN (Shai / Micheal inputs please) ** Eliminate the functions for direct access to gnuplot from Octave.
--- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,8 @@ +2008-08-28 David Bateman <dbateman@free.fr> + + * interpreter/plot.txi: Add description of data sources and line + series objects. + 2008-08-26 David Bateman <dbateman@free.fr> * interpreter/plot.txi: Document the group objects (bar, stem,
--- a/doc/interpreter/plot.txi +++ b/doc/interpreter/plot.txi @@ -581,6 +581,12 @@ @DOCSTRING(drawnow) +Only figures that are modified will be updated. The @code{refresh} +function can also be to force an update of the current figure, even if +it is nor modified. + +@DOCSTRING(refresh) + Normally, high-level plot functions like @code{plot} or @code{mesh} call @code{newplot} to initialize the state of the current axes so that the next plot is drawn in a blank window with default property settings. To @@ -636,7 +642,7 @@ * Image Properties:: * Patch Properties:: * Surface Properties:: -* Seacrhing Properties:: +* Searching Properties:: @end menu @node Root Figure Properties @@ -1196,8 +1202,8 @@ future version of Octave. @end table -@node Seacrhing Properties -@subsubsection Seacrhing Properties +@node Searching Properties +@subsubsection Searching Properties @DOCSTRING(findobj) @@ -1473,7 +1479,22 @@ @noindent that adds a @code{linestyle} property to the @code{hggroup} and -propagating any changes its its value to the children of the group. +propagating any changes its its value to the children of the group. The +@code{linkprop} function can be used to simplify the above to be + +@example +@group +x = 0:0.1:10; +hg = hggroup (); +h1 = plot (x, sin (x), "color", [1, 0, 0], "parent", hg); +addproperty ("linestyle", hg, "linelinestyle", get (h, "linestyle")); +hold on +h2 = plot (x, cos (x), "color", [0, 1, 0], "parent", hg); +hlink = linkprop ([hg, h1, h2], "color"); +@end group +@end example + +@DOCSTRING(linkprop) These capabilities are used in a number of basic graphics objects. The @code{hggroup} objects created by the functions of Octave contain @@ -1520,6 +1541,7 @@ corresponding hggroup elements. @menu +* Data sources in object groups:: * Area series:: * Bar series:: * Contour groups:: @@ -1532,6 +1554,18 @@ * Surface group:: @end menu +@node Data sources in object groups +@subsubsection Data sources in object groups + +All of the group objects contain data source parameters. There are +string parameters that contain an expression that is evaluated to update +the relevant data property of the group when the @code{refreshdata} +function is called. + +@DOCSTRING(refreshdata) + +@c add the description of the linkdata function here when it is written + @node Area series @subsubsection Area series @@ -1557,6 +1591,10 @@ The x and y coordinates of the original columns of the data passed to @code{area} prior to the cummulative summation used in the @code{area} function. + +@item xdatasource +@itemx ydatasource +Data source variables. @end table @node Bar series @@ -1607,6 +1645,10 @@ @item ydata The y value of the bars in the @code{hggroup}. + +@item xdatasource +@itemx ydatasource +Data source variables. @end table @node Contour groups @@ -1622,7 +1664,39 @@ @node Line series @subsubsection Line series -TO BE WRITTEN +line series objects are created by the @code{plot} and @code{plot3} +functions. Each @code{hggroup} element of the series contains a single +line object as a child representing the stair. The properties of the +line series are a one-to-one reflection of the children line object, and +so the line series is only useful for its ability to add data sources to +the group object. + +The properties of the line series are + +@table @code +@item color +The RGB color or color name of the line objects of the stairs. @xref{Colors}. + +@item linewidth +@itemx linestyle +The line width and style of the line objects of the stairs. @xref{Line Styles}. + +@item marker +@itemx markeredgecolor +@itemx markerfacecolor +@itemx markersize +The line and fill color of the markers on the stairs. @xref{Colors}. + +@item xdata +@itemx ydata +@itemx zdata +The original x, y and z data of the stairs. + +@item xdatasource +@itemx ydatasource +@itemx zdatasource +Data source variables. +@end table @node Quiver group @subsubsection Quiver group @@ -1670,6 +1744,14 @@ @itemx vdata @itemx wdata The values of the vector field to plot. + +@item xdatasource +@itemx ydatasource +@itemx zdatasource +@itemx udatasource +@itemx vdatasource +@itemx wdatasource +Data source variables. @end table @node Scatter group @@ -1701,6 +1783,10 @@ @item xdata @itemx ydata The original x and y data of the stairs. + +@item xdatasource +@itemx ydatasource +Data source variables. @end table @node Surface group @@ -1711,6 +1797,8 @@ @node Graphics backends @subsection Graphics backends +@DOCSTRING(backends) + @DOCSTRING(available_backends) @menu
--- a/scripts/ChangeLog +++ b/scripts/ChangeLog @@ -1,3 +1,16 @@ +2008-08-28 David Bateman <dbateman@free.fr> + + * plot/__add_line_series__.m, plot/ishghandle.m, plot/linkprop.m, + plot/refresh.m, plot/refreshdata.m: New functions + * Makefile.in (SOURCES): Add them here. + + * plot/__area__.m, plot/__bars__.m, plot/__quiver__.m, + plot/__stem__.m, plot/stairs.m, plot/stem.m: Add data sources. + + * plot/__plt2mm__.m, plot/__plt2mv__.m, plot/__plt2ss__.m, + plot/__plt2sv__.m, plot/__plt2vm__.m, plot/__plt2vs__.m, + plot/__plt2vv__.m, plot/plot3.m: Add line series and data sources. + 2008-08-28 Martin Weiser <weiser2@natur.cuni.cz> * plot/scatter3.m: Doc fix.
--- a/scripts/plot/Makefile.in +++ b/scripts/plot/Makefile.in @@ -34,6 +34,8 @@ INSTALL_DATA = @INSTALL_DATA@ SOURCES = \ + __add_datasource__.m \ + __add_line_series__.m \ __area__.m \ __axes_limits__.m \ __axis_label__.m \ @@ -120,9 +122,11 @@ hist.m \ hold.m \ isfigure.m \ + ishghandle.m \ ishold.m \ legend.m \ line.m \ + linkprop.m \ loglog.m \ loglogerr.m \ mesh.m \ @@ -145,6 +149,8 @@ print.m \ quiver.m \ quiver3.m \ + refresh.m \ + refreshdata.m \ replot.m \ ribbon.m \ rose.m \
new file mode 100644 --- /dev/null +++ b/scripts/plot/__add_datasource__.m @@ -0,0 +1,51 @@ +## Copyright (C) 2008 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 newargs = __add_datasource__ (fcn, h, data, varargin) + + if (nargin < 3) + error ("internal error"); + endif + + if (ischar (data)) + data = {data}; + endif + + for i = 1 : numel (data) + addproperty (strcat (data{i}, "datasource"), h, "string", ""); + endfor + + i = 1; + newargs = {}; + while (i < numel (varargin)) + arg = varargin{i++}; + if (ischar (arg) && length (arg > 1) && strcmpi (arg(2:end), "datasource")) + arg = tolower (arg); + val = varargin{i++}; + if (ischar (val)) + set (h, arg, val); + else + error ("%s: expecting data source to be a string", fcn); + endif + else + newargs{end + 1} = arg; + endif + endwhile +endfunction
new file mode 100644 --- /dev/null +++ b/scripts/plot/__add_line_series__.m @@ -0,0 +1,64 @@ +## Copyright (C) 2008 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 __add_line_series__ (h, hg) + + obj = get(h); + + addproperty ("color", hg, "linecolor", obj.color); + addproperty ("linewidth", hg, "linelinewidth", obj.linewidth); + addproperty ("linestyle", hg, "linelinestyle", obj.linestyle); + addproperty ("marker", hg, "linemarker", obj.marker); + addproperty ("markeredgecolor", hg, "linemarkerfacecolor", + obj.markeredgecolor); + addproperty ("markerfacecolor", hg, "linemarkerfacecolor", + obj.markerfacecolor); + addproperty ("markersize", hg, "linemarkersize", obj.markersize); + + addlistener (hg, "color", @update_props); + addlistener (hg, "linewidth", @update_props); + addlistener (hg, "linestyle", @update_props); + addlistener (hg, "marker", @update_props); + addlistener (hg, "markeredgecolor", @update_props); + addlistener (hg, "markerfacecolor", @update_props); + addlistener (hg, "markersize", @update_props); + + addproperty ("xdata", hg, "data", obj.xdata); + addproperty ("ydata", hg, "data", obj.ydata); + addproperty ("zdata", hg, "data", obj.zdata); + + addlistener (hg, "xdata", @update_props); + addlistener (hg, "ydata", @update_props); + addlistener (hg, "zdata", @update_props); +endfunction + +function update_props (h, d) + set (get (h, "children"), "color", get (h, "color"), + "linewidth", get (h, "linewidth"), + "linestyle", get (h, "linestyle"), + "marker", get (h, "marker"), + "markerfacecolor", get (h, "markerfacecolor"), + "markeredgecolor", get (h, "markeredgecolor"), + "markersize", get (h, "markersize"), + "xdata", get (h, "xdata"), + "ydata", get (h, "ydata"), + "zdata", get (h, "zdata")); +endfunction +
--- a/scripts/plot/__area__.m +++ b/scripts/plot/__area__.m @@ -25,6 +25,9 @@ retval = []; for i = 1: size (y, 2); hg = hggroup (); + retval = [retval; hg]; + args = __add_datasource__ ("area", hg, {"x", "y"}, varargin{:}); + x1 = x(:, 1).'; y1 = y (:, i).'; addproperty ("xdata", hg, "data", x1); @@ -35,11 +38,11 @@ if (i == 1) h = patch (ax, [x1(1), x1, fliplr(x1)], [bv, y1, bv*ones(1, length(y1))], - __next_line_color__ (), "parent", hg, varargin{:}); + __next_line_color__ (), "parent", hg, args{:}); else y1 = y0 + y1; h = patch (ax, [x1(1), x1, fliplr(x1)], [y0(1), y1, fliplr(y0)], - __next_line_color__ (), "parent", hg, varargin{:}); + __next_line_color__ (), "parent", hg, args{:}); endif y0 = y1; @@ -57,7 +60,6 @@ addlistener (hg, "linestyle", @update_props); addlistener (hg, "facecolor", @update_props); - retval = [retval; hg]; addproperty ("areagroup", hg, "data"); set (retval, "areagroup", retval); endfor
--- a/scripts/plot/__bars__.m +++ b/scripts/plot/__bars__.m @@ -29,7 +29,8 @@ for i = 1:ycols hg = hggroup (); tmp = [tmp; hg]; - + args = __add_datasource__ ("bar", hg, {"x", "y"}, varargin{:}); + if (vertical) if (! have_color_spec) if (ycols == 1) @@ -38,9 +39,9 @@ lev = (i - 1) * (clim(2) - clim(1)) / (ycols - 1) - clim(1); endif h = patch(xb(:,:,i), yb(:,:,i), "FaceColor", "flat", - "cdata", lev, "parent", hg, varargin{:}); + "cdata", lev, "parent", hg, args{:}); else - h = patch(xb(:,:,i), yb(:,:,i), "parent", hg, varargin{:}); + h = patch(xb(:,:,i), yb(:,:,i), "parent", hg, args{:}); endif else if (! have_color_spec) @@ -50,9 +51,9 @@ lev = (i - 1) * (clim(2) - clim(1)) / (ycols - 1) - clim(1); endif h = patch(yb(:,:,i), xb(:,:,i), "FaceColor", "flat", - "cdata", lev, "parent", hg, varargin{:}); + "cdata", lev, "parent", hg, args{:}); else - h = patch(yb(:,:,i), xb(:,:,i), "parent", hg, varargin{:}); + h = patch(yb(:,:,i), xb(:,:,i), "parent", hg, args{:}); endif endif
--- a/scripts/plot/__plt2mm__.m +++ b/scripts/plot/__plt2mm__.m @@ -54,9 +54,17 @@ if (isempty (color)) color = __next_line_color__ (); endif - retval(i) = line (x(:,i), y(:,i), "keylabel", tkey, "color", color, - "linestyle", options(i).linestyle, - "marker", options(i).marker, properties{:}); + + hg = hggroup (); + retval(i) = hg; + args = __add_datasource__ ("__plt2mm__", hg, {"x", "y", "z"}, + properties{:}); + + h = line (x(:,i), y(:,i), "keylabel", tkey, "color", color, + "linestyle", options(i).linestyle, + "marker", options(i).marker, "parent", hg, args{:}); + + __add_line_series__ (h, hg); endfor else error ("__plt2mm__: arguments must be a matrices");
--- a/scripts/plot/__plt2mv__.m +++ b/scripts/plot/__plt2mv__.m @@ -70,9 +70,17 @@ if (isempty (color)) color = __next_line_color__ (); endif - retval(i) = line (x(:,i), y, "keylabel", tkey, "color", color, - "linestyle", options(i).linestyle, - "marker", options(i).marker, properties{:}); + + hg = hggroup (); + retval(i) = hg; + args = __add_datasource__ ("__plt2mv__", hg, {"x", "y", "z"}, + properties{:}); + + h = line (x(:,i), y, "keylabel", tkey, "color", color, + "linestyle", options(i).linestyle, + "marker", options(i).marker, "parent", hg, args{:}); + + __add_line_series__ (h, hg); endfor else error ("__plt2mv__: arguments must be a matrices");
--- a/scripts/plot/__plt2ss__.m +++ b/scripts/plot/__plt2ss__.m @@ -51,9 +51,17 @@ if (isempty (color)) color = __next_line_color__ (); endif - retval = line (x, y, "keylabel", key, "color", color, - "linestyle", options.linestyle, - "marker", options.marker, properties{:}); + + hg = hggroup (); + retval = hg; + properties = __add_datasource__ ("__plt2ss__", hg, {"x", "y", "z"}, + properties{:}); + + h = line (x, y, "keylabel", key, "color", color, + "linestyle", options.linestyle, + "marker", options.marker, "parent", hg, properties{:}); + + __add_line_series__ (h, hg); else error ("__plt2ss__: arguments must be scalars"); endif
--- a/scripts/plot/__plt2sv__.m +++ b/scripts/plot/__plt2sv__.m @@ -50,9 +50,17 @@ if (isempty (color)) color = __next_line_color__ (); endif - retval(i) = line (x, y(i), "keylabel", tkey, "color", color, - "linestyle", options(i).linestyle, - "marker", options(i).marker, properties{:}); + + hg = hggroup (); + retval(i) = hg; + args = __add_datasource__ ("__plt2sv__", hg, {"x", "y", "z"}, + properties{:}); + + h = line (x, y(i), "keylabel", tkey, "color", color, + "linestyle", options(i).linestyle, + "marker", options(i).marker, "parent", hg, args{:}); + + __add_line_series__ (h, hg); endfor else error ("__plt2sv__: first arg must be scalar, second arg must be vector");
--- a/scripts/plot/__plt2vm__.m +++ b/scripts/plot/__plt2vm__.m @@ -70,9 +70,18 @@ if (isempty (color)) color = __next_line_color__ (); endif - retval(i) = line (x, y(:,i), "keylabel", tkey, "color", color, - "linestyle", options(i).linestyle, - "marker", options(i).marker, properties{:}); + + hg = hggroup (); + retval(i) = hg; + args = __add_datasource__ ("__plt2vm__", hg, {"x", "y", "z"}, + properties{:}); + + h = line (x, y(:,i), "keylabel", tkey, "color", color, + "linestyle", options(i).linestyle, + "marker", options(i).marker, "parent", hg, args{:}); + + __add_line_series__ (h, hg); + endfor else error ("__plt2vm__: arguments must be a matrices");
--- a/scripts/plot/__plt2vs__.m +++ b/scripts/plot/__plt2vs__.m @@ -50,9 +50,17 @@ if (isempty (color)) color = __next_line_color__ (); endif - retval(i) = line (x(i), y, "keylabel", tkey, "color", color, - "linestyle", options(i).linestyle, - "marker", options(i).marker, properties{:}); + + hg = hggroup (); + retval(i) = hg; + args = __add_datasource__ ("__plt2vs__", hg, {"x", "y", "z"}, + properties{:}); + + h = line (x(i), y, "keylabel", tkey, "color", color, + "linestyle", options(i).linestyle, + "marker", options(i).marker, "parent", hg, args{:}); + + __add_line_series__ (h, hg); endfor else error ("__plt2vs__: first arg must be vector, second arg must be scalar");
--- a/scripts/plot/__plt2vv__.m +++ b/scripts/plot/__plt2vv__.m @@ -65,9 +65,17 @@ if (isempty (color)) color = __next_line_color__ (); endif - retval = line (x, y, "keylabel", key, "color", color, - "linestyle", options.linestyle, - "marker", options.marker, properties{:}); + + hg = hggroup (); + retval = hg; + properties = __add_datasource__ ("__plt2vv__", hg, {"x", "y", "z"}, + properties{:}); + + h = line (x, y, "keylabel", key, "color", color, + "linestyle", options.linestyle, + "marker", options.marker, "parent", hg, properties{:}); + + __add_line_series__ (h, hg); else error ("__plt2vv__: vector lengths must match"); endif
--- a/scripts/plot/__quiver__.m +++ b/scripts/plot/__quiver__.m @@ -75,6 +75,7 @@ have_filled = false; have_line_spec = false; + args = {}; while (ioff <= nargin) arg = varargin{ioff++}; if (ischar (arg) && strncmp (tolower (arg), "filled", 6)) @@ -88,10 +89,16 @@ linespec.linestyle = "-"; endif else - error ("quiver: invalid linespec"); + args {end + 1} = arg; + if (ioff <= nargin) + args {end + 1} = varargin{ioff++}; + endif endif else - error ("quiver: unrecognized argument"); + args {end + 1} = arg; + if (ioff <= nargin) + args {end + 1} = varargin{ioff++}; + endif endif endwhile @@ -120,6 +127,13 @@ hstate = get (h, "nextplot"); unwind_protect hg = hggroup (); + if (is3d) + args = __add_datasource__ ("quiver3", hg, + {"x", "y", "z", "u", "v", "w"}, args{:}); + else + args = __add_datasource__ ("quiver", hg, + {"x", "y", "z", "u", "v", "w"}, args{:}); + endif hold on; addproperty ("xdata", hg, "data", x); @@ -157,23 +171,23 @@ [y.'; yend.'; NaN(1, length (y))](:), [z.'; zend.'; NaN(1, length (z))](:), "linestyle", linespec.linestyle, - "color", linespec.color, "parent", hg); + "color", linespec.color, "parent", hg, args{:}); else h1 = plot ([x.'; xend.'; NaN(1, length (x))](:), [y.'; yend.'; NaN(1, length (y))](:), "linestyle", linespec.linestyle, - "color", linespec.color, "parent", hg); + "color", linespec.color, "parent", hg, args{:}); endif else if (is3d) h1 = plot3 ([x.'; xend.'; NaN(1, length (x))](:), [y.'; yend.'; NaN(1, length (y))](:), [z.'; zend.'; NaN(1, length (z))](:), - "parent", hg); + "parent", hg, args{:}); else h1 = plot ([x.'; xend.'; NaN(1, length (x))](:), [y.'; yend.'; NaN(1, length (y))](:), - "parent", hg); + "parent", hg, args{:}); endif endif
--- a/scripts/plot/__stem__.m +++ b/scripts/plot/__stem__.m @@ -31,7 +31,8 @@ [ax, varargin, nargin] = __plt_get_axis_arg__ (caller, varargin{:}); - [x, y, z, dofill, llc, ls, mmc, ms] = check_stem_arg (have_z, varargin{:}); + [x, y, z, dofill, llc, ls, mmc, ms, varargin] = ... + check_stem_arg (have_z, varargin{:}); oldax = gca (); unwind_protect @@ -58,6 +59,8 @@ hg = hggroup (); h = [h; hg]; + __add_datasource__ (caller, hg, {"x", "y", "z"}, varargin{:}); + if (i == 1) set (ax, "nextplot", "add"); endif @@ -147,7 +150,7 @@ end_unwind_protect endfunction -function [x, y, z, dofill, lc, ls, mc, ms] = check_stem_arg (have_z, varargin) +function [x, y, z, dofill, lc, ls, mc, ms, newargs] = check_stem_arg (have_z, varargin) if (have_z) caller = "stem3"; @@ -155,6 +158,21 @@ caller = "stem"; endif + ## Remove prop/val pairs from data to consider + i = 2; + newargs = {}; + while (i < length (varargin)) + if (ischar (varargin{i}) && !(strcmpi ("fill", varargin{i}) || + strcmpi ("filled", varargin{i}))) + newargs{end + 1} = varargin{i}; + newargs{end + 1} = varargin{i + 1}; + nargin = nargin - 2; + varargin(i:i+1) = []; + else + i++; + endif + endwhile + ## set specifiers to default values [lc, ls, mc, ms] = set_default_values (); dofill = 0;
new file mode 100644 --- /dev/null +++ b/scripts/plot/ishghandle.m @@ -0,0 +1,28 @@ +## Copyright (C) 2008 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/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {} ishghandle (@var{h}) +## Return true if @var{h} is a graphics handle and false otherwise.\n\ +## @end deftypefn + +function retval = ishghandle (h) + ## This function is just included for compatibility as Octave has + ## no simulink equivalent. + retval = ishandle (h); +endfunction
new file mode 100644 --- /dev/null +++ b/scripts/plot/linkprop.m @@ -0,0 +1,98 @@ +## Copyright (C) 2008 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/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{hlink} =} linkprop (@var{h}, @var{prop}) +## Links graphics object properties, such that a change in one is +## propagated to the others. The properties to link are given as a +## string of cell string array by @var{prop} and the objects containing +## these properties by the handle array @var{h}. +## +## An example of the use of linkprops is +## +## @example +## @group +## x = 0:0.1:10; +## subplot (1, 2, 1); +## h1 = plot (x, sin (x)); +## subplot (1, 2, 2); +## h2 = plot (x, cos (x)); +## hlink = linkprop ([h1, h2], @{"color","linestyle"@}); +## set (h1, "color", "green"); +## set (h2, "linestyle", "--"); +## @end group +## @end example +## +## @end deftypefn + +function hlink = linkprop (h, prop) + if (ischar (prop)) + prop = {prop}; + elseif (!iscellstr (prop)) + error ("linkprop: properties must be a string or cell string array"); + endif + + for i = 1 : numel (h) + for j = 1 : numel (prop) + addlistener (h(i), prop{j}, {@update_prop, h, prop{j}}); + endfor + endfor + + ## This should be an object that when destroyed removes the links + ## The below is not quite right. As when you call "clear hlink" the + ## hggroup continues to exist. + hlink = hggroup (); + set (hlink, "deletefcn", {@delete_prop, h, prop}); +endfunction + +function update_prop (h, d, hlist, prop) + persistent recursion = false; + + ## Don't allow recursion + if (! recursion) + unwind_protect + recursion = true; + val = get (h, prop); + for hh = hlist(:)' + if (hh != h) + oldval = get (hh, prop); + if (! isequal (val, oldval)) + set (hh, prop, val); + endif + endif + endfor + unwind_protect_cleanup + recursion = false; + end_unwind_protect + endif +endfunction + +function delete_prop (h, d, hlist, prop) + ## FIXME. Actually need to delete the linked properties. + ## However, only warn if the graphics objects aren't being deleted. + warn = false; + for h = hlist(:)' + if (ishandle (h) && !strcmp (get (h, "beingdeleted"), "on")) + warn = true; + break; + endif + endfor + if (warn) + warning ("linkprop: can not remove linked properties"); + endif +endfunction
--- a/scripts/plot/plot3.m +++ b/scripts/plot/plot3.m @@ -225,9 +225,15 @@ color = __next_line_color__ (); endif - tmp(++idx) = line (x(:), y(:), z(:), "keylabel", key, "color", color, - "linestyle", options.linestyle, - "marker", options.marker, properties{:}); + hg = hggroup (); + tmp(++idx) = hg; + properties = __add_datasource__ ("plot3", hg, {"x", "y", "z"}, properties{:}); + + hline = line (x(:), y(:), z(:), "keylabel", key, "color", color, + "linestyle", options.linestyle, + "marker", options.marker, "parent", hg, properties{:}); + + __add_line_series__ (h, hg); x = new; y_set = 0; @@ -289,9 +295,15 @@ color = __next_line_color__ (); endif - tmp(++idx) = line (x(:), y(:), z(:), "keylabel", key, "color", color, - "linestyle", options.linestyle, - "marker", options.marker, properties{:}); + hg = hggroup (); + tmp(++idx) = hg; + properties = __add_datasource__ ("plot3", hg, {"x", "y", "z"}, properties{:}); + + hline = line (x(:), y(:), z(:), "keylabel", key, "color", color, + "linestyle", options.linestyle, + "marker", options.marker, "parent", hg, properties{:}); + + __add_line_series__ (h, hg); endif set (gca (), "view", [-37.5, 30]);
new file mode 100644 --- /dev/null +++ b/scripts/plot/refresh.m @@ -0,0 +1,42 @@ +## Copyright (C) 2008 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/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {} refresh () +## @deftypefnx {Function File} {} refresh (@var{h}) +## Refresh a figure, forcing it to be redrawn. Called without an +## argument the current figure is redrawn, otherwise the figure pointed +## to by @var{h} is redrawn. +## @seealso{drawnow} +## @end deftypefn + +function refresh (h) + + if (nargin == 1) + if (!ishandle (h) || !strcmp (get (h, "type"), "figure")) + error ("refresh: expecting argument to be a valid figure handle"); + endif + elseif (nargin > 1) + print_usage (); + else + h = gcf (); + endif + + set(h,"__modified__", "on") + drawnow (); +endfunction
new file mode 100644 --- /dev/null +++ b/scripts/plot/refreshdata.m @@ -0,0 +1,107 @@ +## Copyright (C) 2008 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/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {} refreshdata () +## @deftypefnx {Function File} {} refreshdata (@var{h}) +## @deftypefnx {Function File} {} refreshdata (@var{h}, @var{ws}) +## Evaluates any datasource properties of the current figure and updates +## the corresponding data. If call with one or more arguments @var{h} is +## a scalar or array of figure handles which to refresh. The data +## sources are by default evaluated in the "base" workspace but can also +## be set in the "caller" workspace. +## +## An example of the use of refreshdata is +## +## @example +## @group +## x = 0:0.1:10; +## y = sin (x); +## plot (x, y, "ydatasource", "y"); +## for i = 1 : 100 +## pause(0.1) +## y = sin (x + 0.1 * i); +## refreshdata(); +## endfor +## @end group +## @end example +## +## @seealso{linkdata} +## @end deftypefn + +function refreshdata (h, ws) + + if (nargin == 0) + h = gcf (); + ws = "base"; + else + if (iscell (h)) + h = [h{:}]; + endif + if (!all (ishandle (h)) || !all (strcmp (get (h, "type"), "figure"))) + error ("refreshdata: expecting a list of figure handles"); + endif + if (nargin < 2) + ws = "base"; + else + if (!ischar (ws) || !(strcmpi (ws, "base") || strcmpi (ws, "caller"))) + error ("refreshdata: expecting workspace to be \"base\" or ""caller\""); + else + ws = tolower (ws); + endif + endif + endif + + h = findall (h); + objs = []; + props = {}; + + for i = 1 : numel (h) + obj = get (h (i)); + fldnames = fieldnames (obj); + m = regexpi (fieldnames(obj), "^.datasource$", "match"); + idx = cellfun (@(x) !isempty(x), m); + if (any (idx)) + props = [props; {cell2mat(m(idx))}]; + objs = [objs ; h(i)]; + endif + endfor + + for i = 1 : length (objs) + for j = 1 : length (props {i}) + expr = get (objs(i), props{i}{j}); + if (!isempty (expr)) + val = evalin (ws, expr); + prop = props{i}{j}(1:end-6); + if (! isequal (get (objs(i), prop), val)) + set (objs(i), props{i}{j}(1:end-6), val); + endif + endif + endfor + endfor +endfunction + +%!demo +%! x = 0:0.1:10; +%! y = sin (x); +%! plot (x, y, "ydatasource", "y"); +%! for i = 1 : 100 +%! pause(0.1) +%! y = sin (x + 0.1 * i); +%! refreshdata(); +%! endfor
--- a/scripts/plot/stairs.m +++ b/scripts/plot/stairs.m @@ -81,8 +81,8 @@ function [h, xs, ys] = __stairs__ (doplot, varargin) if (nargin == 1 || ischar (varargin{2})) - idx = 1; y = varargin {1}; + varargin(1) = []; if (ismatrix (y)) if (isvector (y)) y = y(:); @@ -90,9 +90,9 @@ x = 1:rows (y); endif else - idx = 2; x = varargin{1}; y = varargin{2}; + varargin(1:2) = []; endif if (ndims (x) > 2 || ndims (y) > 2) @@ -144,6 +144,7 @@ for i = 1 : size(y, 2) hg = hggroup (); h = [h; hg]; + args = __add_datasource__ ("stairs", hg, {"x", "y"}, varargin{:}); if (i == 1) set (gca (), "nextplot", "add"); @@ -156,7 +157,7 @@ addlistener (hg, "ydata", @update_data); tmp = line (xs(:,i).', ys(:,i).', "color", __next_line_color__ (), - "parent", hg, varargin{idx+1:end}); + "parent", hg, args{:}); addproperty ("color", hg, "linecolor", get (tmp, "color")); addproperty ("linewidth", hg, "linelinewidth", get (tmp, "linewidth"));
--- a/scripts/plot/stem.m +++ b/scripts/plot/stem.m @@ -71,7 +71,7 @@ function h = stem (varargin) - if (nargin < 1 || nargin > 3) + if (nargin < 1) print_usage (); endif