Draw 2D histogram in few granular colors, within limited z-axis range

Here is an example of my use case: I have four detector elements, whose current state I need to depict as a 2x2 2D plot. Five colours must roughly represent the values.

Red:    2<v
Orange: 1<v<2
Green:    v<1
Green: -1<v
Azure: -2<v<-1
Blue:     v<-2

The following code works as desired ONLY if at least one value gets into the “positive saturation” range, i.e. Red:2<v:

{
    Int_t colors[6];
    colors[5] = kRed   +2;
    colors[4] = kOrange+2;
    colors[3] = kGreen +2;
    colors[2] = kGreen +2;
    colors[1] = kAzure +2;
    colors[0] = kBlue+2;
    gStyle->SetPalette(6, colors);
    gStyle->SetNumberContours(6);
    TCanvas* c = new TCanvas("c", "c", 400, 400);
    TH2F*    h = new TH2F("h", "h", 2, 0, 2, 2, 0, 2);
    h->SetStats(kFALSE);
    h->SetMaximum( 3.);
    h->SetMinimum(-3.);

    h->SetBinContent(1, 1,  2.5);
    h->SetBinContent(1, 2,  0.5);
    h->SetBinContent(2, 1, -0.5);
    h->SetBinContent(2, 2, -1.5);
    h->Draw("COLZ2");
}

Otherwise, the desired functionality breaks, and some sort of interpolation comes into play. The following variations demonstrate that:

    h->SetBinContent(1, 1,  1.5);
    h->SetBinContent(1, 2,  0.5);
    h->SetBinContent(2, 1, -0.5);
    h->SetBinContent(2, 2, -1.5);
    h->Draw("COLZ2");

    h->SetBinContent(1, 1,  1.5);
    h->SetBinContent(1, 2,  0.5);
    h->SetBinContent(2, 1, -0.5);
    h->SetBinContent(2, 2, -2.5);
    h->Draw("COLZ2");

How can I avoid that?

Thanks!

When I do:

{
    Int_t colors[6];
    colors[5] = kRed   +2;
    colors[4] = kOrange+2;
    colors[3] = kGreen +2;
    colors[2] = kGreen +2;
    colors[1] = kAzure +2;
    colors[0] = kBlue+2;
    gStyle->SetPalette(6, colors);
    gStyle->SetNumberContours(6);
    TCanvas* c = new TCanvas("c", "c", 400, 400);
    TH2F*    h = new TH2F("h", "h", 2, 0, 2, 2, 0, 2);
    h->SetStats(kFALSE);
    h->SetMaximum( 3.);
    h->SetMinimum(-3.);

    h->SetBinContent(1, 1,  2.5);
    h->SetBinContent(1, 2,  0.5);
    h->SetBinContent(2, 1, -0.5);
    h->SetBinContent(2, 2, -1.5);
    h->Draw("COLZ TEXT");
}
```
I get:
<img src="/uploads/default/original/2X/4/47f2da3ddddd0a1b7a88310a2131d4c435b6acec.png" width="398" height="375">

Seems to me it is fine. The printed text in the bin correspond to the color in the palette.

@couet -> This is a bug in ROOT 6 (it’s related to “2” in the drawing option, i.e. “COLZ” seems to work while “COLZ2” is broken). ROOT 5 works well (“COLZ2” is taken as “COLZ”, I assume).

Yes, but with
h->SetBinContent(1, 1, 1.5);
that same interpolation will happen… :slight_smile:

I see. Thanks.

Unfortunately, all my code is already in C++11, so to say…

Maybe I can somehow checkout the buggy code, repair it and use it locally. Although I must confess, that I have no clue how to do that in this particular context.

Just use “COLZ” instead of “COLZ2”.

Sory, sorry, sorry!

COLZ satisfies me perfectly well !

To eliminate white bins when z<-3., it’s elementary just to add
if (z < -3.) z = -3.;

Thanks a lot everyone!

I think It’s closed now.

Try “COLZ0” instead of this “if”.

@couet -> I noticed another bug. The “TEXT” option does not print the contents of bins which are below the value of “histo->SetMinimum(…)” but it does print the contents of bins which are above the value of “histo->SetMaximum(…)”. This happens for both ROOT 5 and 6.

1 Like

COLZ0 is just what’s needed!

As to printing the contents, I simply do a clone before setting the limits and then superimpose it. So our example becomes “perfect” as follows:

    Int_t colors[6];
    colors[5] = kRed   +2;
    colors[4] = kOrange+2;
    colors[3] = kGreen +2;
    colors[2] = kGreen +2;
    colors[1] = kAzure +2;
    colors[0] = kBlue  +2;
    gStyle->SetPalette(6, colors);
    gStyle->SetNumberContours(6);
    TCanvas* c = new TCanvas("c", "c", 400, 400);
    TH2F*    h = new TH2F("h", "h", 2, 0, 2, 2, 0, 2);
    h->SetStats(kFALSE);
    h->SetBinContent(1, 1,  2.5);
    h->SetBinContent(1, 2,  0.5);
    h->SetBinContent(2, 1, -1.5);
    h->SetBinContent(2, 2, -3.5);
    TH2F*    t = (TH2F*)h->Clone();

    h->SetMaximum( 3.);
    h->SetMinimum(-3.);
    h->Draw("COLZ0");

    t->SetMarkerSize(1.8);
    t->SetMarkerColor(kWhite);
    t->Draw("TEXT SAME");

Thanks everyone again!

Cheers

@Wile_E_Coyote I will check col2

And what about “TEXT”? I guess one cannot have “TEXT0” as it would interfere with the existing “TEXTnn”.

Well, I know that with another drawing options, bins above “histo->SetMaximum(…)” are always “painted” but I don’t really understand why this difference was introduced (bins below “histo->SetMinimum(…)” are “white”).
However, if we need to “clone” the histogram in order to get all bins printed … then I vote that by default BOTH types, i.e. below “histo->SetMinimum(…)” an above “histo->SetMaximum(…)”, are NOT printed.

I ran again the macro using option COL2Z I get exactly the same plot I got with COLZ. I am using the master version of ROOT on mac.

With the TEXT option the empty bins are not drawn. Yes TEXT0 will draw text at angle 0. as shown here:
https://root.cern/doc/master/classTHistPainter.html#HP15

Just to make sure … did you try to change “h->SetBinContent(1, 1, 2.5);” into “h->SetBinContent(1, 1, 1.5);”? Using ROOT v6.10.00, I get a correct colour for “COLZ” and an incorrect one for “COLZ2”.

BTW. I just noticed that “COLZ2” does “paint” bins below “histo->SetMinimum(…)” (and this is inconsistent with the behaviour of “COLZ”, which leaves them “white”). A simple test is to change “h->SetBinContent(2, 2, -1.5);” into “h->SetBinContent(2, 2, -3.5);”.

I did not… so I redid the two plot using:

   h->SetBinContent(1, 1,  2.5);
   h->SetBinContent(1, 2,  1.5);
   h->SetBinContent(2, 1, -0.5);
   h->SetBinContent(2, 2, -1.5);

I get:

COLZ

COL2Z[quote=“Wile_E_Coyote, post:13, topic:25256”]
I just noticed that “COLZ2” does “paint” bins below “histo->SetMinimum(…)” (and this is inconsistent with the behaviour of “COLZ”, which leaves them “white”).
[/quote]

Yes COL2 is a complete different code whit was implemented for fast rendering … “pixmap way”

Yes, with bins set like you have, I also get the same pictures. In order to see the “COLZ2” bug, I need to “h->SetBinContent(1, 1, 1.5);” (note: the actual maximum bin contents in the histogram must change).

Ah yes … I see it now … weird.
1.5 gives a wrong colour with COL2

To summarise: the following macro shows that COL2Z et COLZ do not give the same result.

{
   Int_t colors[6];
   colors[5] = kRed   +2;
   colors[4] = kOrange+2;
   colors[3] = kGreen +2;
   colors[2] = kGreen +2;
   colors[1] = kAzure +2;
   colors[0] = kBlue+2;
   gStyle->SetPalette(6, colors);
   gStyle->SetNumberContours(6);
   TCanvas* c = new TCanvas("c", "c", 800, 400);
   c->Divide(2,1);

   TH2F*    h = new TH2F("h", "h", 2, 0, 2, 2, 0, 2);
   h->SetStats(kFALSE);
   h->SetMaximum( 3.);
   h->SetMinimum(-3.);

   h->SetBinContent(1, 1,  1.5);
   h->SetBinContent(1, 2,  0.5);
   h->SetBinContent(2, 1, -0.5);
   h->SetBinContent(2, 2, -1.5);

   c->cd(1); h->Draw("COLZ TEXT");
   c->cd(2); h->Draw("COL2Z TEXT");
}

When I over and over hear people saying this to me, it strikes me again and again that I had made a terrible mistake when choosing profession (a very long time ago).
I should had become an ophthalmologist. In this profession, I would have much more success than in what I have to fight against now. I could work wonders … even now, having no any ophthalmological training at all, I can easily make people start to SEE, just by talking to them.

2 Likes

Using COL is fine, but for some reasons, I do not understand (yet), COL2 is not ok with the following macro. It seems TImage get it wrong when the maximum value does not appear in the plot. There is some code in THistPainter dealing with that case already but it does not work in that case. Also using the default palette (which has more colors) makes it work…

{
   Int_t colors[6];
   colors[5] = kRed   +2;
   colors[4] = kOrange+2;
   colors[3] = kGreen +2;
   colors[2] = kGreen ;
   colors[1] = kAzure +2;
   colors[0] = kBlue+2;
   gStyle->SetPalette(6, colors);
   gStyle->SetNumberContours(6);
   TCanvas* c = new TCanvas("c", "c", 800, 400);
   c->Divide(2,1);

   TH2F*    h = new TH2F("h", "h", 1, 0, 2, 6, 0, 7);
   h->SetMarkerSize(5.);
   h->SetMarkerColor(kWhite);
   h->SetStats(kFALSE);
   h->SetMaximum( 3.);

   h->SetBinContent(1, 1, -1.5);
   h->SetBinContent(1, 2, -0.5);
   h->SetBinContent(1, 3,  0.5);
   h->SetBinContent(1, 4,  1.0);
   h->SetBinContent(1, 5,  1.5);
//   h->SetBinContent(1, 6,  2.5); uncommenting this line make it works

   c->cd(1); h->Draw("COLZ TEXT");
   c->cd(2); h->Draw("COL2Z TEXT");
}

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.