bugGNU Octave - Bugs: bug #59589, default color in bar (and hist)...


bug #59589: default color in bar (and hist) plots is different from Matlab

Submitter:  Hartmut <hardy>
Submitted:  Tue 01 Dec 2020 05:17:09 PM UTC
Category:  Plotting Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Matlab Compatibility
Status:  Fixed Assigned to:  None
Originator Name:  Open/Closed:  * Closed
Release:  * dev Operating System:  * Any
* Mandatory Fields

Add a New Comment (Rich Markup)

Comment Type & Canned Response:


( Jump to the original submission )

Sat 05 Dec 2020 12:05:28 PM UTC, comment #12: 

As to comment #10 ...

> but the best course for the future is probably to implement the histogram() function

... there's a patch for the histogram and histcounts functions since 2015, actually two since October 2018, see patch #8801.

I've included the original functions by Lars + some fixes by me since ages in my builds. There are apparently a few wrinkles to iron out but I wasn't affected by it so left those to be done (see comments #6 - #8 in patch #8801).
I didn't test the second patch there (currently just histcounts).

Philip Nienhuis <philipnienhuis>
Project Member
Sat 05 Dec 2020 01:50:28 AM UTC, comment #11: 

I pushed one more changeset (http://hg.savannah.gnu.org/hgweb/octave/rev/3000414c60eb) which now has bar() returning a bar object for "stacked" and "grouped" inputs and a patch object for "hist" and "histc".

It seems that the code for the Bar object was created a while ago and that Matlab has added properties in newer releases.  That could be the subject of a different bug report.

Rik <rik5>
Project Administrator
Fri 04 Dec 2020 05:12:44 PM UTC, comment #10: 

It's clear that Matlab took their old function for hist and their new function for bar charts and just merged them together without much thought.  The syntax "bar (x)" returns a Bar object while "bar (x, 'hist')" returns an entirely different object (a Patch object).  Apparently Matlab didn't think much of their idea either because they no longer recommend using hist() to create histogram plots.  Instead, the list of Matlab functions (https://www.mathworks.com/help/matlab/referencelist.html?type=function) now suggests using histogram() which returns its own special graphics object which is neither a Bar or Patch object.

I suppose Octave can do the same thing and propagate the mess to our code base.  This is why it grows tiresome to try and chase Matlab compatibility.

The "FaceColor" property is immaterial here.  The underlying patch object for a rectangle (bar) has four points.  Matlab chose to specify color data for each of the four points (they used the same value) and because they had specified the color at all four points they also needed to tell the OpenGL renderer how to interpret colors between the points.  For a value of "Flat", no interpretation is done and the "FaceColor" is taken form the first vertex of the rectangle.

Octave chose to minimize memory storage and stores just one color for each rectangles (1/4 of the memory used).  Because there is only one color per rectangle the OpenGL renderer doesn't need any further instruction, "Flat" or "Interp", to decide how to proceed.

I'll see what I can do with what we have, but the best course for the future is probably to implement the histogram() function and deprecate hist().

Rik <rik5>
Project Administrator
Fri 04 Dec 2020 08:42:55 AM UTC, comment #9: 

I have recompiled and retested this:

  • The color in the bar plot (first part of code in  comment #0) is still light blue, and as such fully Matlab compatible as before.
  • The color in the hist plot is now greenish-blueish (last part of code in comment #0). This color is NOT the same as in Matlab, and also the property 'FaceColor' does not have the same content as in Matlab.
  • hist plot in Matlab: color [0.239, 0.149, 0.659] (dark blue)
    • property 'FaceColor' is 'flat'
  • hist plot in dev Octave (as of Dec 4): color [0 0.569 0.541 (green-blue)
    • property 'FaceColor' is 'interp'

I have no clue about the logic behind this color mess. But for me the version before gave nicer colors (patch from comment #4), and the newest version (patch from comment #8) does not seem to be any "better" in terms of compatibility.

Hartmut <hardy>
Fri 04 Dec 2020 01:49:20 AM UTC, comment #8: 

I updated Octave to be fully Matlab-compatible here:

Now the programmer has two choices about where default color data will come from.  Either the "ColorOrder" property if the options "stacked" or "grouped" are present or the "ColorMap" property if "hist" or "histc" is given.

Rik <rik5>
Project Administrator
Thu 03 Dec 2020 11:52:53 PM UTC, comment #7: 

Okay, thanks for testing with Matlab.  What Matlab is doing is a combination of what we had before and what we have now.  For an ordinary bar chart the colors come from the "ColorOrder" property.  For a histogram, the colors come from the "Colormap" property of the axes or figure.  On Matlab, try the hist plot and then try

colormap ('autumn')

This should turn the histogram bright red.

I can implement this for compatibility, but you probably won't like the colors chosen.  The first color is always the first color in the colormap which for Octave's default colormap of "viridis" is a dark purple.

Rik <rik5>
Project Administrator
Thu 03 Dec 2020 09:29:24 PM UTC, comment #6: 

I have new compiled a "fresh" dev Octave and tested this behavior, including Rik's patch from comment #4. Result:

  • The color produced with a simple call to bar(), not using any special arguments, seems now to be compatible with Matlab. Perfect.
  • But the color produced with hist() is still DIFFERENT from the color in Matlab. (or with bar(...,'hist'))

clear, close all, clc
x = rand(1,20);
h = bar(x, 'hist'); % which I think is the same as: hist(x)
histcolor = get(h, 'FaceColor')

  • result in Matlab:  'flat', and via Gimp on screenshot: [0.239, 0.149, 0.659] (dark blue).
  • result in Octave (including patch from comment #4): [0 0.447 0.7410] (light blue).

my conclusions:

  • Also for hist() the compatibility to Matlab colors is now much better than before. They both use a blueish color.
  • But hist() still produces a different (blue) color. And this seems also to be a qualitative difference, because Octave returns 3 numbers, but Matlab just returns the string 'flat', as property of the FaceColor.

I cannot judge if it is worth to pursue even better Matlab compatibility in this issue. Strictly speaking this issue is NOT solved as fixed. But I personally would already be happy with the current result.

Hartmut <hardy>
Thu 03 Dec 2020 08:37:11 AM UTC, comment #5: 

Wow, thanks for your fast reaction.

I am still struggeling to verify this change works as intended. When I simply copy the files _bar_.m and _next_line_color_.m from the dev branch in the repo into my existing Octave 6.1 installation, then I still get the same violet color in the figures from my code in comment #0. But I will try to compile the full dev branch now and see if it works there.

Hartmut <hardy>
Wed 02 Dec 2020 07:50:40 PM UTC, comment #4: 

Okay.  I pushed a changeset for this feature here: http://hg.savannah.gnu.org/hgweb/octave/rev/8bb14f4979ca.

Marking as fixed and closing report.

Rik <rik5>
Project Administrator
Wed 02 Dec 2020 05:26:16 PM UTC, comment #3: 

I had a look into _bar_.m and couldn't even find where this code currently uses the colormap property. That's why I decided to leave this topic open for someone who has more insight into Occtave's graphics internals than me.

Hartmut <hardy>
Tue 01 Dec 2020 07:17:42 PM UTC, comment #2: 

For testing, you can use

bar (rand (3,10))

This will produce three groups of 10 bars each.  Since the "colororder" property only contains 7 colors this will cause some colors to be re-used.

Rik <rik5>
Project Administrator
Tue 01 Dec 2020 07:16:20 PM UTC, comment #1: 

In Matlab 2017b, they switched from using colors from the "colormap" property of the axes or figure to using colors from the "colororder" property.  That is the root incompatibility.

For example, this reproduces the same result as Matlab

h = bar (1:5);
set (h, 'facecolor', get (gca, 'colororder')(1,:))
get (h, 'facecolor')
ans =

        0   0.4470   0.7410

I don't think there would be any objection if you wanted to modify _bar_.m to use "colororder".

Rik <rik5>
Project Administrator
Tue 01 Dec 2020 05:17:09 PM UTC, original submission:  

This report is about the color used in bar() and hist() plots, when used without any additional color options. In this case the colors in Octave (both intense violet) are different from the colors used in Matlab plots (light and dark blue). This might be connected to the change of default colormap to viridis some time ago.

Here is code to reproduce the behavior. I will also attach two SCREENSHOTS showing the resulting plots in Octave (6.1) and Matlab (R2019b) respectively:

clear, close all, clc
x = rand(1,20);

% color in bar plot:
hbar = bar(x);
barcolor = get(hbar, 'FaceColor')
% result in Matlab: [0 0.447 0.741] (light blue)
% result in Octave: 'flat', and via Gimp on screenshot: [0.267, 0.400, 0.329] (violet)

% idea where this color (in Matlab) comes from: (light blue)
colororder = get(gca, 'ColorOrder');
colororder1 = colororder(1,:)
% result (in Matlab and Octave): [0 0.477, 0.741] (light blue)

% color in hist plot
hbar2 = bar(x, 'hist'); % which I think is the same as: hist(x)
histcolor = get(hbar2, 'FaceColor')
% result in Matlab: 'flat', and via Gimp on screenshot: [0.239, 0.149, 0.659] (dark blue)
% result in Octave: 'flat', and via Gimp in screenshot: [0.267, 0.400, 0.329] (violet)

This might mostly be an aesthetic problem, since one can always change the colors used by Octave plots. Nevertheless this "aggressivly" violet color used by Octave doesn't fit well into the colors used in most other Octave plots and has therefore bothered my for quite some time already.

Hartmut <hardy>


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

Attach Files:

Attached Files
file #50368:  Screenshot_Matlab.png added by hardy (39KiB - image/png)
file #50369:  Screenshot_Octave.png added by hardy (35KiB - image/png)


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 hardy (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 project members can vote.





    Follow 5 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2020-12-02 rik5 StatusNone Fixed
        Open/ClosedOpen Closed
    2020-12-01 rik5 Release6.1.0 dev
    2020-12-01 hardy Attached File- Added Screenshot_Matlab.png, #50368
        Attached File- Added Screenshot_Octave.png, #50369

    Back to the top

    Powered by Savane 3.9