changeset 22419:be969d43d95f

Rework color scaling for gnuplot toolkit (bug #48664) * __gnuplot_draw_axes__.m: Remove 'cdatadirect' variable and operate directly on individual object property 'cdatamapping'. Remove 'truecolor' variable. If axes cautoscale is set, do a first pass to get the 'clim' min and max of 'cdata' for all objects having 'scale' for 'cdatamapping' property. If the number of rows in the color map is not two, do a second pass to check for any image data that is logical. If logical image found, set axis parent color map to black/white, axis 'clim' to [0 1] and 'climmode' to 'manual'. Set 'cmap' and 'cmap_sz' variables before the axes children loop. If "image", "patch" or "surface" object has 'cdatamapping' property set to scale, linearly scale color data according to 'clim' using fix--not round--with range clamping. The one exception is "image" with logical 'cdata' in which case 1 is added to the data (equivalent of 'clim' of [0 1]). Simplify the logic for setting gnuplot cbrange to [1,cmap_sz] or [1,cmap_sz+row(addedcmap)] for extended color maps.
author Daniel J Sebald <daniel.sebald@ieee.org>
date Sat, 06 Aug 2016 02:27:11 -0500
parents 08aa03dfb00e
children e5ae26e50374
files scripts/plot/util/private/__gnuplot_draw_axes__.m
diffstat 1 files changed, 104 insertions(+), 39 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/plot/util/private/__gnuplot_draw_axes__.m	Thu Sep 01 13:22:03 2016 -0700
+++ b/scripts/plot/util/private/__gnuplot_draw_axes__.m	Sat Aug 06 02:27:11 2016 -0500
@@ -430,8 +430,6 @@
   yautoscale = strcmp (axis_obj.ylimmode, "auto");
   zautoscale = strcmp (axis_obj.zlimmode, "auto");
   cautoscale = strcmp (axis_obj.climmode, "auto");
-  cdatadirect = false;
-  truecolor = false;
 
   fputs (plot_stream, "set clip two;\n");
 
@@ -455,9 +453,75 @@
   hidden_removal = NaN;
   view_map = false;
 
-  if (! cautoscale && clim(1) == clim(2))
+  if (cautoscale)
+    ## First pass to get cdata limits, maybe general graphics should do this
+    kids1 = kids;
+    clim = [Inf -Inf];
+
+    while (! isempty (kids1))
+      obj = get (kids1(end));
+      kids1 = kids1(1:(end-1));
+
+      switch (obj.type)
+        case {"image", "patch", "surface"}
+          if (isfield (obj, "cdatamapping")
+              && strcmp (obj.cdatamapping, "scaled")
+              && isfield (obj, "cdata")
+              && ! isempty (obj.cdata))
+            clim(1) = min (clim(1), min (obj.cdata(:)));
+            clim(2) = max (clim(2), max (obj.cdata(:)));
+          endif
+
+        case "hggroup"
+          ## Push group children into the kid list.
+          if (isempty (kids1))
+            kids1 = obj.children;
+          elseif (! isempty (obj.children))
+            kids1 = [kids1; obj.children];
+          endif
+      endswitch
+    endwhile
+
+    if (clim(1) == Inf)
+      clim = axis_obj.clim;
+    endif
+
+  elseif (clim(1) == clim(2))
     clim(2)++;
   endif
+
+  if (rows (parent_figure_obj.colormap) != 2)
+    ## Second pass to change color map for binary images (not sure correct)
+    kids1 = kids;
+    while (! isempty (kids1))
+      obj = get (kids1(end));
+      kids1 = kids1(1:(end-1));
+
+      switch (obj.type)
+        case {"image"}
+          if (isfield (obj, "cdata") && islogical (obj.cdata))
+            set (axis_obj.parent, "colormap", [0 0 0; 1 1 1]);
+            set (h, "clim", [0 1]);
+            set (h, "climmode", "manual");
+            parent_figure_obj.colormap = [0 0 0; 1 1 1];
+            axis_obj.clim = [0 1];
+            axis_obj.climmode = "manual";
+            break;
+          endif
+
+        case "hggroup"
+          ## Push group children into the kid list.
+          if (isempty (kids1))
+            kids1 = obj.children;
+          elseif (! isempty (obj.children))
+            kids1 = [kids1; obj.children];
+          endif
+      endswitch
+    endwhile
+  endif
+
+  cmap = parent_figure_obj.colormap;
+  cmap_sz = rows (cmap);
   addedcmap = [];
 
   ximg_data = {};
@@ -515,10 +579,15 @@
         img_xdata = obj.xdata;
         img_ydata = obj.ydata;
 
-        if (ndims (img_data) == 3)
-          truecolor = true;
-        elseif (strcmp (obj.cdatamapping, "direct"))
-          cdatadirect = true;
+        if (ndims (img_data) != 3)
+          if (islogical (img_data))
+            img_data += 1;
+          else
+            if (strcmp (obj.cdatamapping, "scaled"))
+              img_data = 1 + fix (cmap_sz*(img_data-clim(1))/(clim(2)-clim(1)));
+            endif
+            img_data = max (1, min (img_data, cmap_sz));
+          endif
         endif
         data_idx += 1;
         is_image_data(data_idx) = true;
@@ -667,14 +736,10 @@
         endif
 
       case "patch"
-        cmap = parent_figure_obj.colormap;
         [nr, nc] = size (obj.xdata);
 
         if (! isempty (obj.cdata))
           cdat = obj.cdata;
-          if (strcmp (obj.cdatamapping, "direct"))
-            cdatadirect = true;
-          endif
         else
           cdat = [];
         endif
@@ -754,39 +819,47 @@
                       ## RGB Triplet
                       color = ccol;
                     elseif (nd == 3 && numel (xcol) == 3)
-                      ccdat = ccol;
+                      if (strcmp (obj.cdatamapping, "scaled"))
+                        ccdat = 1 + fix (cmap_sz*(ccol-clim(1))/(clim(2)-clim(1)));
+                      else
+                        ccdat = ccol;
+                      endif
+                      ccdat = max (1, min (ccdat, cmap_sz));
                     else
-                      if (cdatadirect)
+                      if (strcmp (obj.cdatamapping, "direct"))
                         r = round (ccol);
                       else
-                        r = 1 + round ((rows (cmap) - 1)
-                                       * (ccol - clim(1))/(clim(2) - clim(1)));
+                        r = 1 + fix (cmap_sz*(ccol-clim(1))/(clim(2)-clim(1)));
                       endif
-                      r = max (1, min (r, rows (cmap)));
+                      r = max (1, min (r, cmap_sz));
                       color = cmap(r, :);
                     endif
                   elseif (strcmp (obj.facecolor, "interp"))
                     if (nd == 3 && numel (xcol) == 3)
                       ccdat = ccol;
                       if (! isvector (ccdat))
-                        tmp = rows (cmap) + rows (addedcmap) + ...
+                        tmp = cmap_sz + rows (addedcmap) + ...
                              [1 : rows(ccdat)];
                         addedcmap = [addedcmap; ccdat];
                         ccdat = tmp(:);
                       else
-                        ccdat = ccdat(:);
+                        if (strcmp (obj.cdatamapping, "scaled"))
+                          ccdat = 1 + fix (cmap_sz*(ccdat(:)-clim(1))/(clim(2)-clim(1)));
+                        else
+                          ccdat = ccdat(:);
+                        endif
+                        ccdat = max (1, min (ccdat, cmap_sz));
                       endif
                     else
                       if (sum (diff (ccol)))
                         warning ("\"interp\" not supported, using 1st entry of cdata");
                       endif
-                      if (cdatadirect)
+                      if (strcmp (obj.cdatamapping, "direct"))
                         r = round (ccol);
                       else
-                        r = 1 + round ((rows (cmap) - 1)
-                                       * (ccol - clim(1))/(clim(2) - clim(1)));
+                        r = 1 + fix (cmap_sz*(ccol-clim(1))/(clim(2)-clim(1)));
                       endif
-                      r = max (1, min (r, rows (cmap)));
+                      r = max (1, min (r, cmap_sz));
                       color = cmap(r(1),:);
                     endif
                   endif
@@ -801,7 +874,7 @@
 
               if (nd == 3 && numel (xcol) == 3)
                 if (isnan (ccdat))
-                  ccdat = (rows (cmap) + rows (addedcmap) + 1) * ones(3, 1);
+                  ccdat = (cmap_sz + rows (addedcmap) + 1) * ones(3, 1);
                   addedcmap = [addedcmap; reshape(color, 1, 3)];
                 elseif (numel (ccdat) == 1)
                   ccdat = ccdat * ones (size (zcol));
@@ -1149,6 +1222,10 @@
         ydat = obj.ydata;
         zdat = obj.zdata;
         cdat = obj.cdata;
+        if (strcmp (obj.cdatamapping, "scaled"))
+          cdat = 1 + fix (cmap_sz*(cdat-clim(1))/(clim(2)-clim(1)));
+        endif
+        cdat = max (1, min (cdat, cmap_sz));
         err = false;
         if (! size_equal (zdat, cdat))
           err = true;
@@ -1404,24 +1481,12 @@
     fprintf (plot_stream, "set zrange [%.15e:%.15e];\n", zlim);
   endif
 
-  cmap = parent_figure_obj.colormap;
-  cmap_sz = rows (cmap);
   if (! any (isinf (clim)))
-    if (truecolor || ! cdatadirect)
-      if (rows (addedcmap) > 0)
-        for i = 1:data_idx
-          if (have_3d_patch(i))
-            data{i}(end,:) = clim(2) * (data{i}(end, :) - 0.5) / cmap_sz;
-           endif
-        endfor
-        fprintf (plot_stream, "set cbrange [%.15e:%.15e];\n",
-                 clim(1), clim(2) * (cmap_sz + rows (addedcmap)) / cmap_sz);
-      else
-        fprintf (plot_stream, "set cbrange [%.15e:%.15e];\n", clim);
-      endif
+    if (rows (addedcmap) > 0)
+      fprintf (plot_stream, "set cbrange [1:%.15e];\n",
+               cmap_sz + rows (addedcmap));
     else
-      fprintf (plot_stream, "set cbrange [1:%d];\n", cmap_sz +
-               rows (addedcmap));
+      fprintf (plot_stream, "set cbrange [1:%.15e];\n", cmap_sz);
     endif
   endif