Error using TColor

Dear experts,

I am encountering a problem using TColor to set the fill colors of histograms. In the past, I wrote a script that would set fill colors for histograms and then save them to a TFile as in this example:
tcolor-step1.py (292 Bytes)

and they would appear as expected (i.e. with the desired fill color) if I opened them from the TFile as in this example:
tcolor-step2.py (116 Bytes)

However, now the same script which used to work that way does not work for me in my current version of ROOT (6.14/06 running on macOS Mojave). I see errors like this when I try:

jhakala@JHakBookPro ~ # python -i tcolor-step1.py
>>> .q
jhakala@JHakBookPro ~ # python -i tcolor-step2.py
Error in <TGQuartz::DrawFillArea>: Could not find TColor for index 1179
>>> .q

(In this example, I see a properly filled histogram after running tcolor-step1.py but I see an empty histogram after running tcolor-step2.py.)

It is odd that this used to work but no longer does. Please let me know if there is a fix for this, or how else I might define custom colors for filling histograms that can be successfully saved to a TFile.

Thanks
-John

I made a JIRA report:
https://sft.its.cern.ch/jira/browse/ROOT-10722

Do you remember with which version it was working ?

Thinking of it this color is not defined when you redisplay the canvas. So it is normal it is not found:

root [0] gROOT->GetColor(1179)
(TColor *) nullptr

The color definition is not saved with the histogram. It has always been like that. If you save the canvas (as .C file for instance) you will see the color definition is saved. But I cannot imagine in which ROOT version what you are doing was working. It would really help me to investigate if you tell me in which one it is supposed to work.

In ROOT 5, it returns color “924” and ROOT 6 returns a valid pointer for this color (maybe old files were used with new ROOT?).

Well, the default color “924” in ROOT 6 looks a bit similar to the newly created color “924” in ROOT 5 so one may “fail to notice” that there is something really different.

Anyhow, on Linux / X11, even if the color does not exist (1179), I do not get any verbose error when drawing the histogram (the non-existent “fill color” is not drawn, of course).

Yes but is it the right color ? I guess not.

@couet
I believe the version I was using when this was working was 6.10/08 on macOS.

Indeed there is now a new functionality named
TColor ::SetColorThreshold()

By default, when GetColor() is used, the exact R G B values are tried to be find in the existing color palette and if this color is not found a new color is created. That’s what is done in your case.

But if you accept to have a color a little bit different but close enough to what you asked you can give a little bit more freedom to the way the closest color is defined by changing the Color Threshold.

For instance in your case you can do:

root [0] TColor::SetColorThreshold(0.1);
root [1] Int_t ci;
root [2] Float_t r = .3, g = .4, b = .5;
root [3] ci = TColor::GetColor(r, g, b);
root [4] printf("%d\n",ci);
431

and 431 exists in the predefined color palette so you will not get the problem you had when you display back the histogram.

You can put:

 TColor::SetColorThreshold(0.1);

in your rootlogon.C file

Great, that works quite nicely. Thanks @couet!