changeset 28289:068f6190616b

__gnuplot_scatter__.m: Add missing file (bug #58282). * scripts/plot/draw/private/__gnuplot_scatter__.m: Add file missing from commit 496735a910c1. * scripts/plot/draw/private/__scatter__.m: Add missing argument for __gnuplot_scatter__. * scripts/plot/draw/module.mk: Add new file to build system.
author Markus Mützel <markus.muetzel@gmx.de>
date Sun, 10 May 2020 21:02:54 +0200
parents baac2c55e236
children c198760f2915
files scripts/plot/draw/module.mk scripts/plot/draw/private/__gnuplot_scatter__.m scripts/plot/draw/private/__scatter__.m
diffstat 3 files changed, 347 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/plot/draw/module.mk	Sun May 10 20:36:31 2020 +0200
+++ b/scripts/plot/draw/module.mk	Sun May 10 21:02:54 2020 +0200
@@ -9,6 +9,7 @@
   %reldir%/private/__contour__.m \
   %reldir%/private/__errplot__.m \
   %reldir%/private/__ezplot__.m \
+  %reldir%/private/__gnuplot_scatter__.m \
   %reldir%/private/__interp_cube__.m \
   %reldir%/private/__line__.m \
   %reldir%/private/__marching_cube__.m \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/plot/draw/private/__gnuplot_scatter__.m	Sun May 10 21:02:54 2020 +0200
@@ -0,0 +1,345 @@
+########################################################################
+##
+## Copyright (C) 2020 The Octave Project Developers
+##
+## See the file COPYRIGHT.md in the top-level directory of this
+## distribution or <https://octave.org/copyright/>.
+##
+## 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
+## <https://www.gnu.org/licenses/>.
+##
+########################################################################
+
+## -*- texinfo -*-
+## @deftypefn {} {@var{hg} =} __gnuplot_scatter__ (@dots{})
+## Undocumented internal function.
+## @end deftypefn
+
+function hg = __gnuplot_scatter__ (hax, fcn, x, y, z, c, s, marker, filled, newargs)
+
+if (isempty (c))
+  c = __next_line_color__ ();
+endif
+
+## Must occur after __next_line_color__ in order to work correctly.
+hg = hggroup (hax, "__appdata__", struct ("__creator__", "__scatter__"));
+newargs = __add_datasource__ (fcn, hg, {"x", "y", "z", "c", "size"},
+                              newargs{:});
+
+addproperty ("xdata", hg, "data", x);
+addproperty ("ydata", hg, "data", y);
+addproperty ("zdata", hg, "data", z);
+if (ischar (c))
+  ## For single explicit color, cdata is unused
+  addproperty ("cdata", hg, "data", []);
+else
+  addproperty ("cdata", hg, "data", c);
+endif
+addproperty ("sizedata", hg, "data", s);
+addlistener (hg, "xdata", @update_data);
+addlistener (hg, "ydata", @update_data);
+addlistener (hg, "zdata", @update_data);
+addlistener (hg, "cdata", @update_data);
+addlistener (hg, "sizedata", @update_data);
+
+one_explicit_color = ischar (c) || isequal (size (c), [1, 3]);
+s = sqrt (s);  # size adjustment for visual compatibility w/Matlab
+
+if (numel (x) <= 100)
+
+  ## For small number of points, we'll construct an object for each point.
+
+  if (numel (s) == 1)
+    s = repmat (s, numel (x), 1);
+  endif
+
+  if (one_explicit_color)
+    for i = 1 : numel (x)
+      if (filled)
+        __go_patch__ (hg, "facecolor", "none", "edgecolor", "none",
+                      "xdata", x(i), "ydata", y(i), "zdata", z(i,:),
+                      "faces", 1, "vertices", [x(i), y(i), z(i,:)],
+                      "marker", marker,  "markersize", s(i),
+                      "markeredgecolor", c, "markerfacecolor", c,
+                      "linestyle", "none");
+      else
+        __go_patch__ (hg, "facecolor", "none", "edgecolor", "none",
+                      "xdata", x(i), "ydata", y(i), "zdata", z(i,:),
+                      "faces", 1, "vertices", [x(i), y(i), z(i,:)],
+                      "marker", marker,  "markersize", s(i),
+                      "markeredgecolor", c, "markerfacecolor", "none",
+                      "linestyle", "none");
+      endif
+    endfor
+  else
+    if (rows (c) == 1)
+      c = repmat (c, rows (x), 1);
+    endif
+    for i = 1 : numel (x)
+      if (filled)
+        __go_patch__ (hg, "facecolor", "none", "edgecolor", "none",
+                      "xdata", x(i), "ydata", y(i), "zdata", z(i,:),
+                      "faces", 1, "vertices", [x(i), y(i), z(i,:)],
+                      "marker", marker, "markersize", s(i),
+                      "markeredgecolor", "none",
+                      "markerfacecolor", "flat",
+                      "cdata", c(i,:), "facevertexcdata", c(i,:),
+                      "linestyle", "none");
+      else
+        __go_patch__ (hg, "facecolor", "none", "edgecolor", "none",
+                      "xdata", x(i), "ydata", y(i), "zdata", z(i,:),
+                      "faces", 1, "vertices", [x(i), y(i), z(i,:)],
+                      "marker", marker, "markersize", s(i),
+                      "markeredgecolor", "flat",
+                      "markerfacecolor", "none",
+                      "cdata", c(i,:), "facevertexcdata", c(i,:),
+                      "linestyle", "none");
+      endif
+    endfor
+  endif
+
+else
+
+  ## For larger numbers of points, we use one single object.
+  vert = [x, y, z];
+  render_size_color (hg, vert, s, c, marker, filled, true);
+
+endif
+
+if (! ischar (c) && rows (c) > 1)
+  ax = get (hg, "parent");
+  clim = get (ax, "clim");
+  if (min (c(:)) < clim(1))
+    clim(1) = min (c(:));
+    set (ax, "clim", clim);
+  endif
+  if (max (c(:)) > clim(2))
+    set (ax, "clim", [clim(1), max(c(:))]);
+  endif
+endif
+
+addproperty ("linewidth", hg, "patchlinewidth", 0.5);
+addproperty ("marker", hg, "patchmarker", marker);
+if (filled)
+  addproperty ("markeredgecolor", hg, "patchmarkeredgecolor", "none");
+  if (one_explicit_color)
+    addproperty ("markerfacecolor", hg, "patchmarkerfacecolor", c);
+  else
+    addproperty ("markerfacecolor", hg, "patchmarkerfacecolor", "flat");
+  endif
+else
+  addproperty ("markerfacecolor", hg, "patchmarkerfacecolor", "none");
+  if (one_explicit_color)
+    addproperty ("markeredgecolor", hg, "patchmarkeredgecolor", c);
+  else
+    addproperty ("markeredgecolor", hg, "patchmarkeredgecolor", "flat");
+  endif
+endif
+addlistener (hg, "linewidth", @update_props);
+addlistener (hg, "marker", @update_props);
+addlistener (hg, "markerfacecolor", @update_props);
+addlistener (hg, "markeredgecolor", @update_props);
+
+## Matlab property, although Octave does not implement it.
+addproperty ("hittestarea", hg, "radio", "on|{off}", "off");
+
+if (! isempty (newargs))
+  set (hg, newargs{:});
+endif
+
+endfunction
+
+function render_size_color (hg, vert, s, c, marker, filled, isflat)
+
+  if (isempty (c))
+    c = __next_line_color__ ();
+  endif
+
+  if (isscalar (s))
+    x = vert(:,1);
+    y = vert(:,2);
+    z = vert(:,3:end);
+    toolkit = get (ancestor (hg, "figure"), "__graphics_toolkit__");
+    ## Does gnuplot only support triangles with different vertex colors ?
+    ## FIXME: Verify gnuplot can only support one color.  If RGB triplets
+    ##        can be assigned to each vertex, then fix __gnuplot_draw_axes__.m
+    gnuplot_hack = (numel (x) > 1 && columns (c) == 3
+                    && strcmp (toolkit, "gnuplot"));
+    if (ischar (c) || ! isflat || gnuplot_hack)
+      if (filled)
+        ## "facecolor" and "edgecolor" must be set before any other properties
+        ## to skip co-planarity check (see bug #55751).
+        __go_patch__ (hg, "facecolor", "none", "edgecolor", "none",
+                          "xdata", x, "ydata", y, "zdata", z,
+                          "faces", 1:numel (x), "vertices", vert,
+                          "marker", marker,
+                          "markeredgecolor", "none",
+                          "markerfacecolor", c(1,:),
+                          "markersize", s, "linestyle", "none");
+      else
+        __go_patch__ (hg, "facecolor", "none", "edgecolor", "none",
+                          "xdata", x, "ydata", y, "zdata", z,
+                          "faces", 1:numel (x), "vertices", vert,
+                          "marker", marker,
+                          "markeredgecolor", c(1,:),
+                          "markerfacecolor", "none",
+                          "markersize", s, "linestyle", "none");
+      endif
+    else
+      if (filled)
+        __go_patch__ (hg, "facecolor", "none", "edgecolor", "none",
+                          "xdata", x, "ydata", y, "zdata", z,
+                          "faces", 1:numel (x), "vertices", vert,
+                          "marker", marker, "markersize", s,
+                          "markeredgecolor", "none",
+                          "markerfacecolor", "flat",
+                          "cdata", c, "facevertexcdata", c,
+                          "linestyle", "none");
+      else
+        __go_patch__ (hg, "facecolor", "none", "edgecolor", "none",
+                          "xdata", x, "ydata", y, "zdata", z,
+                          "faces", 1:numel (x), "vertices", vert,
+                          "marker", marker, "markersize", s,
+                          "markeredgecolor", "flat",
+                          "markerfacecolor", "none",
+                          "cdata", c, "facevertexcdata", c,
+                          "linestyle", "none");
+      endif
+    endif
+  else
+    ## Round size to one decimal place.
+    [ss, ~, s_to_ss] = unique (ceil (s*10) / 10);
+    for i = 1:rows (ss)
+      idx = (i == s_to_ss);
+      render_size_color (hg, vert(idx,:), ss(i), c,
+                             marker, filled, isflat);
+    endfor
+  endif
+
+endfunction
+
+function update_props (h, d)
+
+  lw = get (h, "linewidth");
+  m  = get (h, "marker");
+  fc = get (h, "markerfacecolor");
+  ec = get (h, "markeredgecolor");
+  kids = get (h, "children");
+
+  set (kids, "linewidth", lw, "marker", m,
+             "markerfacecolor", fc, "markeredgecolor", ec);
+
+endfunction
+
+## FIXME: This callback routine doesn't handle the case where N > 100.
+function update_data (h, d)
+
+  x = get (h, "xdata");
+  y = get (h, "ydata");
+  z = get (h, "zdata");
+  if (numel (x) > 100)
+    error ("scatter: cannot update data with more than 100 points.  Call scatter (x, y, ...) with new data instead.");
+  endif
+  c = get (h, "cdata");
+  one_explicit_color = ischar (c) || isequal (size (c), [1, 3]);
+  if (! one_explicit_color)
+    if (rows (c) == 1)
+      c = repmat (c, numel (x), 1);
+    endif
+  endif
+  filled = ! strcmp (get (h, "markerfacecolor"), "none");
+  s = get (h, "sizedata");
+  ## Size adjustment for visual compatibility with Matlab.
+  s = sqrt (s);
+  if (numel (s) == 1)
+    s = repmat (s, numel (x), 1);
+  endif
+  hlist = get (h, "children");
+
+  if (one_explicit_color)
+    if (filled)
+      if (isempty (z))
+        for i = 1 : length (hlist)
+          set (hlist(i), "vertices", [x(i), y(i)],
+                         "markersize", s(i),
+                         "markeredgecolor", c, "markerfacecolor", c);
+
+        endfor
+      else
+        for i = 1 : length (hlist)
+          set (hlist(i), "vertices", [x(i), y(i), z(i)],
+                         "markersize", s(i),
+                         "markeredgecolor", c, "markerfacecolor", c);
+        endfor
+      endif
+    else
+      if (isempty (z))
+        for i = 1 : length (hlist)
+          set (hlist(i), "vertices", [x(i), y(i)],
+                         "markersize", s(i),
+                         "markeredgecolor", c, "markerfacecolor", "none");
+
+        endfor
+      else
+        for i = 1 : length (hlist)
+          set (hlist(i), "vertices", [x(i), y(i), z(i)],
+                         "markersize", s(i),
+                         "markeredgecolor", c, "markerfacecolor", "none");
+        endfor
+      endif
+    endif
+  else
+    if (filled)
+      if (isempty (z))
+        for i = 1 : length (hlist)
+          set (hlist(i), "vertices", [x(i), y(i)],
+                         "markersize", s(i),
+                         "markeredgecolor", "none", "markerfacecolor", "flat",
+                         "cdata", reshape (c(i,:),[1, size(c)(2:end)]),
+                         "facevertexcdata", c(i,:));
+        endfor
+      else
+        for i = 1 : length (hlist)
+          set (hlist(i), "vertices", [x(i), y(i), z(i)],
+                         "markersize", s(i),
+                         "markeredgecolor", "none", "markerfacecolor", "flat",
+                         "cdata", reshape (c(i,:),[1, size(c)(2:end)]),
+                         "facevertexcdata", c(i,:));
+        endfor
+      endif
+    else
+      if (isempty (z))
+        for i = 1 : length (hlist)
+          set (hlist(i), "vertices", [x(i), y(i)],
+                         "markersize", s(i),
+                         "markeredgecolor", "flat", "markerfacecolor", "none",
+                         "cdata", reshape (c(i,:),[1, size(c)(2:end)]),
+                         "facevertexcdata", c(i,:));
+        endfor
+      else
+        for i = 1 : length (hlist)
+          set (hlist(i), "vertices", [x(i), y(i), z(i)],
+                         "markersize", s(i),
+                         "markeredgecolor", "flat", "markerfacecolor", "none",
+                         "cdata", reshape (c(i,:),[1, size(c)(2:end)]),
+                         "facevertexcdata", c(i,:));
+        endfor
+      endif
+    endif
+  endif
+
+endfunction
+
--- a/scripts/plot/draw/private/__scatter__.m	Sun May 10 20:36:31 2020 +0200
+++ b/scripts/plot/draw/private/__scatter__.m	Sun May 10 21:02:54 2020 +0200
@@ -171,7 +171,7 @@
 
   if (strcmp ("gnuplot", graphics_toolkit ()))
     ## Legacy code using patch for gnuplot toolkit
-    hs = __gnuplot_scatter__ (hax, fcn, x, y, z, c, s, marker, newargs)
+    hs = __gnuplot_scatter__ (hax, fcn, x, y, z, c, s, marker, filled, newargs);
 
   else
     ## Use OpenGL rendering for "qt" and "fltk" graphics toolkits