bugGNU Octave - Bugs: bug #52624, gnuplot toolkit binary image is...

 
 

bug #52624: gnuplot toolkit binary image is only black pixels

Submitter:  Dan Sebald <sebald>
Submitted:  Fri 08 Dec 2017 10:51:47 AM UTC
   
 
Category:  Plotting with gnuplot Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Incorrect Result
Status:  Fixed Assigned to:  None
Originator Name:  Open/Closed:  * Closed
Release:  * dev Operating System:  * Any
Fixed Release:  None Planned Release:  None
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Wed 13 Dec 2017 08:46:58 PM UTC, comment #10: 

Yes, that's a simpler example that illustrates the difference.  It seems odd it should do that.  For numbers the size of any expected colormap, the whole portion of float mantissa is pretty much the same as integer.

Dan Sebald <sebald>
Wed 13 Dec 2017 08:08:04 PM UTC, comment #9: 

I think the algorithm you have now is right.

The interpretation does depend on the data type (integer vs. float) of the "cdata" property.  Try this example


close all
figure ("colormap", [1 0 0; 0 1 0; 0 0 1]);  # RGB map
h = image ([0 1 2 3 4])
## "cdata" is double, therefore indexing begins at 1
## Displayed color is R R G B B
set (h, "cdata", uint8 ([0 1 2 3 4])
## "cdata" is now integer, indexing begins at 0
## Displayed color is R G B B B


Both FLTK and gnuplot produce the same image for the input above.

Rik <rik5>
Group administrator
Wed 13 Dec 2017 05:49:24 PM UTC, comment #8: 

@Dan: I applied your patch to the stable branch here (http://hg.savannah.gnu.org/hgweb/octave/rev/a9be96afb39e).

As I understand it, this applies to patch colors.  Does something similar need to be done for surface objects?  I ask because I am seeing slight color discrepancies with trimesh.  I'll take the discussion over to bug #42561.

Rik <rik5>
Group administrator
Wed 13 Dec 2017 04:35:40 AM UTC, comment #7: 

Regarding the integer/double indexing, there is still some ambiguity there.  If one accepts the first statement "Interpret the values as indices into the current colormap" as the definition and the rest of the paragraphs as corner cases on either end of the range, then there is no adding 1.  However, if one accepts the later paragraphs as definition, i.e., "If the values are of type [integer], then values of 0 or less map to the first color in the colormap" then it could be construed that 0 is the first entry in the map, 1 is the second entry, 2 the third, etc. which appears to be adding 1 to the integer index.

Generally speaking, color maps and pixel extents are always a confusion at the nitty-gritty given so many libraries and applications to deal with.  I often wish libraries would write a terse math formula rather than try describing behavior.

Dan Sebald <sebald>
Wed 13 Dec 2017 04:24:32 AM UTC, comment #6: 

Oh, interesting, never knew copyobj existed, thanks.

I isolated the graph with the problem.  It is an issue with that zero clim range (i.e., clim(1) == clim(2)).  This scatter demo is using a clim mode of auto, which means clim(1) and clim(2) are the same when there is only a single color.  Attached is a patch that fixes this.  I also changed the case where there is a clim range of zero for TrueColor, but I don't think that ever occurs; higher level code rules out such a combination.

Here are some scripts to test (since it dividing by two I figured I should try even and odd colormap sizes):


close all
m=1;
n=1;
x = rand (n, 1);
y = rand (n, 1);
colors = rand (n, m);
graphics_toolkit fltk
scatter (x, y, [], colors, "filled");
set(gca, 'ColorMap', jet(4));
graphics_toolkit gnuplot
figure
scatter (x, y, [], colors, "filled");
set(gca, 'ColorMap', jet(4));

close all
m=1;
n=1;
x = rand (n, 1);
y = rand (n, 1);
colors = rand (n, m);
graphics_toolkit fltk
scatter (x, y, [], colors, "filled");
set(gca, 'ColorMap', jet(3));
graphics_toolkit gnuplot
figure
scatter (x, y, [], colors, "filled");
set(gca, 'ColorMap', jet(3));

close all
m=1;
n=1;
x = rand (n, 1);
y = rand (n, 1);
colors = rand (n, m);
graphics_toolkit fltk
scatter (x, y, [], colors, "filled");
set(gca, 'ColorMap', jet(1));
graphics_toolkit gnuplot
figure
scatter (x, y, [], colors, "filled");
set(gca, 'ColorMap', jet(1));


I figured I should try a colormap size of one and that revealed gnuplot doesn't like a zero colorbox range.  In such a case I forced it to two and it seems to produce the desired result, so there we go.

(file #42631)

Dan Sebald <sebald>
Wed 13 Dec 2017 03:59:08 AM UTC, comment #5: 

I used copyobj() to get an identical copy.  Sample code:


close all
graphics_toolkit fltk
demo scatter 7
h2 = copyobj (1);
graphics_toolkit (h2, "gnuplot")


For the question about +0 or +1, maybe this description of CDataMapping will help.  There is definitely an offset of 1 between real types (single and double) and integer types.


Color data mapping method, specified as 'direct' or 'scaled'. Use this property to control the mapping of color data values in CData into the colormap. CData must be a vector or a matrix defining indexed colors. This property has no effect if CData is a 3-D array defining true colors.

The methods have these effects:

    'direct' — Interpret the values as indices into the current colormap. Values with a decimal portion are fixed to the nearest lower integer.

        If the values are of type double or single, then values of 1 or less map to the first color in the colormap. Values equal to or greater than the length of the colormap map to the last color in the colormap.

        If the values are of type uint8, uint16, uint32, uint64 , int8, int16, int32, or int64, then values of 0 or less map to the first color in the colormap. Values equal to or greater than the length of the colormap map to the last color in the colormap (or up to the range limits of the type).

        If the values are of type logical, then values of 0 map to the first color in the colormap and values of 1 map to the second color in the colormap.

    'scaled' — Scale the values to range between the minimum and maximum color limits. The CLim property of the axes contains the color limits.


Rik <rik5>
Group administrator
Wed 13 Dec 2017 02:53:27 AM UTC, comment #4: 

I meant that I think both gnuplot and OpenGL toolkits aren't consistent with Matlab.  Since gnuplot is adding 1 to cdata, I assume that is the same as what FLTK is doing.  I don't see why for integers we'd add one but for doubles (passed through fix) we wouldn't add one.  Logical I can understand--it makes no sense for there to be only alternatives 0 and 1 when the colormap starts at 1.

How did you generate these two scatterplot figures with the same data in both the gnuplot toolkit and FLTK toolkit?  Re-calling the demo with a different toolkit creates a different set of data.  I can probably figure this out by writing a script similar to the northeast case, i.e., a single color in a scatter plot.  It could be a "scaled" issue when the color map size is one entry...in fact, that might be this case where "clim_rng" is 0 because there is only a single color:


    if (clim_rng != 0)
      cdata = 255 * (cdata - clim(1)) / clim_rng;
      cdata(cdata < 0) = 0;  cdata(cdata > 255) = 255;
    else
      cdata(:) = 255;
    endif


Maybe 255 is not the value to use.  I'll investigate...

Dan Sebald <sebald>
Wed 13 Dec 2017 02:11:07 AM UTC, comment #3: 

Your patch fixes things for me.  I tried the original motivating example and the extra tests in comment #2.  I pushed it here (http://hg.savannah.gnu.org/hgweb/octave/rev/cb6a61636a23).

Because I can't see a difference between FLTK and gnuplot in the examples, I'm inclined to accept that +1 is necessary.

I don't know if this is related, but check "demo scatter 7" and the northeast plot.  The color of the single dot is different between gnuplot and fltk.  It has been this way for a while.  I've attached the two images.


Rik <rik5>
Group administrator
Wed 13 Dec 2017 01:01:11 AM UTC, comment #2: 

Binary images aren't allowed as RGB (i.e., 3-component) images, so that was a red herring.

The attached patch should put the gnuplot toolkit in sync with the OpenGL toolkits.  It turns out that for scaled images, the logical case is no different than the integer case.  I.e., logical is {0,1} and clim indicates [0 1].  Run that through the formula and it always picks the first or last entry of the colormap no matter the size.  I then also had to add one for the "Direct" mode.

Here are some test scripts to put the various image data formats through their paces relative to OpenGL:


close all;
monoimg(:,:,1) = toeplitz([0:5]) > 2;
graphics_toolkit fltk
figure
h1 = imshow(monoimg);
set(gca, 'ColorMap', jet(4));
set(h1, 'cdatamapping', 'direct');
graphics_toolkit gnuplot
figure
h2 = imshow(monoimg);
set(gca, 'ColorMap', jet(4));
set(h2, 'cdatamapping', 'direct');

close all;
dblimg(:,:,1) = toeplitz([0:5]);
graphics_toolkit fltk
figure
imshow(dblimg/5);
set(gca, 'ColorMap', jet(500));
h1 = imshow(dblimg);
set(gca, 'ColorMap', jet(4));
set(h1, 'cdatamapping', 'direct');
graphics_toolkit gnuplot
figure
imshow(dblimg/5);
set(gca, 'ColorMap', jet(500));
h2 = imshow(dblimg);
set(gca, 'ColorMap', jet(4));
set(h2, 'cdatamapping', 'direct');

close all;
intimg(:,:,1) = uint8(toeplitz([0:5]));
graphics_toolkit fltk
figure
imshow(intimg*100);
set(gca, 'ColorMap', jet(500));
h1 = imshow(intimg);
set(gca, 'ColorMap', jet(4));
set(h1, 'cdatamapping', 'direct');
graphics_toolkit gnuplot
figure
imshow(intimg*100);
set(gca, 'ColorMap', jet(500));
h2 = imshow(intimg);
set(gca, 'ColorMap', jet(4));
set(h2, 'cdatamapping', 'direct');


I've sat for a while thinking about the results, and I'm fine with most everything except perhaps the "Direct" mode applied to integer data.  I'm not sure if we should be adding 1 to the integer data (just as double data doesn't have 1 added).  It might be only the logical case where we should add one.  That is, rather than the image looking like the current appearance in the attached add_one_to_integer_cdata.png, I wonder if it should look like the appearance in attached file not_add_one_to_integer_cdata.png.

(file #42626,

Dan Sebald <sebald>
Fri 08 Dec 2017 04:55:35 PM UTC, comment #1: 

There is probably also a difference in gnuplot versions responsible for this.  I'm running 5.0.3 and the plot is all white as it should be.  But I know you're runnig a more bleeding edge version of gnuplot.

Rik <rik5>
Group administrator
Fri 08 Dec 2017 10:51:47 AM UTC, original submission:  

Try:

monoimg(:,:,1) = logical(ones (128));
% All logical one should be white
graphics_toolkit fltk
figure(1)
imshow(monoimg)
% Not black
graphics_toolkit gnuplot
figure(2)
imshow(monoimg)

This looks like a bug related to the gnuplot rgb range change (0 to 255 is the new default range) similar to the bug identified in http://savannah.gnu.org/bugs/?52599 .  Perhaps all that need be done is to send {0,255} to gnuplot rather than {0,1}.

Dan Sebald <sebald>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by rik5 (Posted a comment)
  • -email is unavailable- added by sebald (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only group members can vote.

     

    Follow 9 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2017-12-13 sebald Attached File- Added octave-gnuplot_zero_color_autorange-djs2017dec12.patch, #42631
    2017-12-13 rik5 Attached File- Added demo.sc7.gnuplot.png, #42629
        Attached File- Added demo.sc7.fltk.png, #42630
        StatusWorks For Me Fixed
        Open/ClosedOpen Closed
    2017-12-13 sebald Attached File- Added octave-gnuplot_opengl_consistent_cmap-djs2017dec12.patch, #42626
        Attached File- Added add_one_to_integer_cdata.png, #42627
        Attached File- Added not_add_one_to_integer_cdata.png, #42628
    2017-12-08 rik5 StatusNone Works For Me

    Back to the top

    Powered by Savane 3.13-758e.
    Corresponding source code