Formatting colour palette with threshold values

Consider this example:


const unsigned char n = 3;
  Int_t colours[n] = {kGreen -10, kGreen -6, kGreen + 1};
  gStyle -> SetPalette(n, colours);
  gStyle -> SetPaintTextFormat("2.2f");
  gStyle -> SetOptStat(0);
  TH2 * h = new TH2F("h", "h", 3, -0.5, 2.5, 3, -0.5, 2.5);
  h -> Fill(0.0, 0.0, 0.62);
  h -> Fill(0.0, 1.0, 0.51);
  h -> Fill(0.0, 2.0, 0.4);

  h -> Fill(1.0, 0.0, 0.2);
  h -> Fill(1.0, 1.0, 0.7);
  h -> Fill(1.0, 2.0, 0.26);

  h -> Fill(2.0, 0.0, 0.1);
  h -> Fill(2.0, 1.0, 0.27);
  h -> Fill(2.0, 2.0, 0.66);

  TCanvas * c = new TCanvas;
  h -> Draw("COLZTEXT");
  h -> SetMarkerSize(3.0);

The output is:

I would like to change the colour palette in the following way:

light green applies to values [ 0.0; 0.5 )
medium green - [ 0.5; 0.6 )
dark green - [0.6; 1.0001]

(the values define important thresholds).

How could I adjust the colour palette in this manner.

@couet will most probably help you (next week)

You want to link the histogram content to the colormap. The following example shows how to do it. You will need to have 2 val_cut instead of one.
https://root.cern/doc/master/perceptualcolormap_8C.html

I modified my example according to ROOT: tutorials/graphics/perceptualcolormap.C File Reference


const unsigned char Number = 6;
  //  Int_t colours[Number] = {kGreen -10, kGreen -6, kGreen + 1};                                                                                                               

  Double_t Red[Number]   =  {0.75, 0.75, 0.0, 0.0, 0.0, 0.0,};
  Double_t Green[Number] =  {1.0,  1.0,  0.3, 0.3, 0.7, 0.7 };
  Double_t Blue[Number]  =  {0.75, 0.75, 0.0, 0.0, 0.0, 0.0 };
  Double_t  Stops[Number] = {0.0,  0.5, 0.50001, 0.6, 0.6000001, 1.0};
  TColor::CreateGradientColorTable(Number, Stops, Red, Green, Blue, 3);
  //  gStyle -> SetPalette(n, colours);                                                                                                                                          
  gStyle -> SetPaintTextFormat("2.2f");
  gStyle -> SetOptStat(0);
  TH2 * h = new TH2F("h", "h", 3, -0.5, 2.5, 3, -0.5, 2.5);
  h -> Fill(0.0, 0.0, 0.62);
  h -> Fill(0.0, 1.0, 0.51);
  h -> Fill(0.0, 2.0, 0.4);

  h -> Fill(1.0, 0.0, 0.2);
  h -> Fill(1.0, 1.0, 0.7);
  h -> Fill(1.0, 2.0, 0.26);

  h -> Fill(2.0, 0.0, 0.1);
  h -> Fill(2.0, 1.0, 0.27);
  h -> Fill(2.0, 2.0, 0.66);
  h -> SetMinimum(0.0);
  h -> SetMaximum(1.0);
  TCanvas * c = new TCanvas;
  h -> Draw("COLZTEXT");
  h -> SetMarkerSize(3.0);

In the output:

  1. why are there 2 colours instead of 3?
  2. why 0.4 is the same colour as 0.51?

How to express light green, medium green and dark green as a combination of RGB?

void viesturs2()
{
   const unsigned char Number = 6;

   Double_t Red[Number]   =  {0.75, 0.75, 0.0,     0.0, 0.0,       0.0,};
   Double_t Green[Number] =  {1.00, 1.00, 0.3,     0.3, 0.7,       0.7 };
   Double_t Blue[Number]  =  {0.75, 0.75, 0.0,     0.1, 0.0,       0.0 };
   Double_t  Stops[Number] = {0.00, 0.50, 0.50001, 0.6, 0.6000001, 1.0};
   TColor::CreateGradientColorTable(Number, Stops, Red, Green, Blue, 10);

   gStyle -> SetPaintTextFormat("2.2f");
   gStyle -> SetOptStat(0);
   TH2 * h = new TH2F("h", "h", 3, -0.5, 2.5, 3, -0.5, 2.5);
   h -> Fill(0.0, 0.0, 0.62);
   h -> Fill(0.0, 1.0, 0.51);
   h -> Fill(0.0, 2.0, 0.4);

   h -> Fill(1.0, 0.0, 0.2);
   h -> Fill(1.0, 1.0, 0.7);
   h -> Fill(1.0, 2.0, 0.26);

   h -> Fill(2.0, 0.0, 0.1);
   h -> Fill(2.0, 1.0, 0.27);
   h -> Fill(2.0, 2.0, 0.66);
   h -> SetMinimum(0.0);
   h -> SetMaximum(1.0);

   TCanvas * c = new TCanvas;
   h -> Draw("COLZTEXT");
   h -> SetMarkerSize(3.0);
}

1 Like

Final question - I added a new TH2 * h2:

const unsigned char Number = 6;
   Int_t colours[Number] = {kGreen -10, kGreen -6, kGreen + 1};

  Double_t Red[Number]   =  {0.75, 0.75, 0.5, 0.5, 0.2, 0.2,};
  Double_t Green[Number] =  {1.0,  1.0,  1.0, 1.0, 1.0, 1.0 };
  Double_t Blue[Number]  =  {0.75, 0.75, 0.5, 0.5, 0.2, 0.2 };
  Double_t  Stops[Number] = {0.0,  0.5, 0.50001, 0.6, 0.6000001, 1.0};


  TColor::CreateGradientColorTable(Number, Stops, Red, Green, Blue, 10);
  //  gStyle -> SetPalette(n, colours);                                                                                                                                          
  gStyle -> SetPaintTextFormat("2.2f");
  gStyle -> SetOptStat(0);
  TH2 * h = new TH2F("h", "h", 3, -0.5, 2.5, 3, -0.5, 2.5);
  h -> Fill(0.0, 0.0, 0.62);
  h -> Fill(0.0, 1.0, 0.51);
  h -> Fill(0.0, 2.0, 0.4);

  h -> Fill(1.0, 0.0, 0.2);
  h -> Fill(1.0, 1.0, 0.7);
  h -> Fill(1.0, 2.0, 0.26);

  h -> Fill(2.0, 0.0, 0.1);
  h -> Fill(2.0, 1.0, 0.27);
  h -> Fill(2.0, 2.0, 0.66);
  h -> SetMinimum(0.0);
  h -> SetMaximum(1.0);
  TCanvas * c = new TCanvas;
  h -> Draw("COLZTEXT");
  h -> SetMarkerSize(3.0);
  TH2 * h2 = new TH2F("h2", "h2", 2, -0.5, 1.5, 2, -0.5, 1.5);
  h2 -> Fill(0.0, 0.0, 2.0);
  h2 -> Fill(0.0, 1.0, 2.5);
  h2 -> Fill(1.0, 0.0, 0.5);
  h2 -> Fill(1.0, 1.0, 1.5);
  TCanvas *c2	= new TCanvas;
  h2 -> Draw("COLZ");

How can I draw the new h2 with the standard ROOT colour palette?

https://root.cern/doc/master/multipalette_8C.html

You can also may be use the CJUST option as shown here.

The example fails when I multiply all stops and bin contents by 100:

  const unsigned char Number = 6;

  Double_t Red[Number]   =  {0.75, 0.75, 0.0,     0.0, 0.0,       0.0,};
  Double_t Green[Number] =  {1.00, 1.00, 0.3,     0.3, 0.7,       0.7 };
  Double_t Blue[Number]  =  {0.75, 0.75, 0.0,     0.1, 0.0,       0.0 };
  //Double_t  Stops[Number] = {0.00, 0.50, 0.50001, 0.6, 0.6000001, 1.0};                                                                                                                                                                                                                                                                                        
  Double_t  Stops[Number] = {0.00, 50.0, 50.001,  60.0,  60.00001, 100.0};
  TColor::CreateGradientColorTable(Number, Stops, Red, Green, Blue, 10);

  gStyle -> SetPaintTextFormat("2.2f");
  gStyle -> SetOptStat(0);
  TH2 * h = new TH2F("h", "h", 3, -0.5, 2.5, 3, -0.5, 2.5);
  h -> Fill(0.0, 0.0, 62.0);
  h -> Fill(0.0, 1.0, 51.0);
  h -> Fill(0.0, 2.0, 40.0);

  h -> Fill(1.0, 0.0, 20.0);
  h -> Fill(1.0, 1.0, 70.0);
  h -> Fill(1.0, 2.0, 26.0);

  h -> Fill(2.0, 0.0, 10.0);
  h -> Fill(2.0, 1.0, 27.0);
  h -> Fill(2.0, 2.0, 66.0);
  h -> SetMinimum(0.0);
  h -> SetMaximum(100.0);

  TCanvas * c = new TCanvas;
  h -> Draw("COLZTEXT");
  h -> SetMarkerSize(3.0);

Could you please help me find what is wrong?

Look at the doc of CreateGradineColorTable . The STOPS values are between 0 and 1 . You removed that part of the code from the original macro I gave you :frowning:

Is there a function to get RGB values of kGreen + 10?

root [0] float r,g,b;
root [1] TColor *color = gROOT->GetColor(kGreen+10);
root [2] color->GetRGB(r,g,b)
root [3] cout << r << " " << g << " " << b << endl;
0.4 0.8 0.8
1 Like

I am trying the mulitpalette example:

void pal();
int palette()
{
  TExec * ex = new TExec("ex", "pal();");
  TH2 * h = new TH2F("h", "h", 3, -0.5, 2.5, 3, -0.5, 2.5);
  h -> Fill(0.0, 0.0, 0.62);
  h -> Fill(0.0, 1.0, 0.51);
  h -> Fill(0.0, 2.0, 0.4);

  h -> Fill(1.0, 0.0, 0.2);
  h -> Fill(1.0, 1.0, 0.7);
  h -> Fill(1.0, 2.0, 0.26);

  h -> Fill(2.0, 0.0, 0.1);
  h -> Fill(2.0, 1.0, 0.27);
  h -> Fill(2.0, 2.0, 0.66);
  h -> SetMinimum(0.0);
  h -> SetMaximum(1.0);
  TCanvas * c = new TCanvas;
  ex -> Draw();
  h -> Draw("COLZTEXTSAME");

  h -> SetMarkerSize(3.0);
  TH2 * h2 = new TH2F("h2", "h2", 2, -0.5, 1.5, 2, -0.5, 1.5);
  h2 -> Fill(0.0, 0.0, 2.0);
  h2 -> Fill(0.0, 1.0, 2.5);
  h2 -> Fill(1.0, 0.0, 0.5);
  h2 -> Fill(1.0, 1.0, 1.5);
  TCanvas *c2 = new TCanvas;
  h2 -> Draw("COLZ");
  return 0;
}

void pal()
{
  const unsigned char Number = 6;
  Int_t colours[Number] = {kGreen -10, kGreen -6, kGreen + 1};
  Double_t Red[Number]   =  {0.75, 0.75, 0.5, 0.5, 0.2, 0.2,};
  Double_t Green[Number] =  {1.0,  1.0,  1.0, 1.0, 1.0, 1.0 };
  Double_t Blue[Number]  =  {0.75, 0.75, 0.5, 0.5, 0.2, 0.2 };
  Double_t  Stops[Number] = {0.0,  0.5, 0.50001, 0.6, 0.6000001, 1.0};
  TColor::CreateGradientColorTable(Number, Stops, Red, Green, Blue, 10);
  gStyle -> SetPaintTextFormat("2.2f");
  gStyle -> SetOptStat(0);

}

TH2 * h is drawn in a very distorted way:

What could I fix?

I see that the right drawing sequence is:

  h -> Draw("COLZTEXT");
  ex -> Draw();
  h -> Draw("COLZTEXTSAME");

I also see that TExec does not execute properly lambda functions. It is yet unclear how to make TExec compatible with a standard C++ project.

No it does not. You should use a normal C++ function.

I am trying to use 2 palettes by creating 2 styles:

void pal1(TStyle * style);
int multiplepalettes()
{
  TStyle * st1 = new TStyle("st1", "my style 1");
  TStyle * st2 = new TStyle("st2", "my style 2");
  pal1(st1);
  gROOT -> SetStyle("st1");
  TH2 * h1 = new TH2F("h1", "h1", 2, -0.5, 1.5, 2, -0.5, 1.5);
  h1 -> Fill(0.0, 0.0, 0.62);
  h1 -> Fill(0.0, 1.0, 0.51);

  h1 -> Fill(1.0, 0.0, 0.2);
  h1 -> Fill(1.0, 1.0, 0.7);

  TCanvas * c1 = new TCanvas;
  h1 -> Draw("COLZTEXT");
  gROOT -> SetStyle("st2");

  TH2 * h2 = new TH2F("h2", "h2", 2, -0.5, 1.5, 2, -0.5, 1.5);
  h2 -> Fill(0.0, 0.0, 2.0);
  h2 -> Fill(0.0, 1.0, 2.5);

  h2 -> Fill(1.0, 0.0, 0.5);
  h2 -> Fill(1.0, 1.0, 1.5);

  TCanvas *c2 = new TCanvas;
  h2 -> Draw("COLZ");
  return 0;
}

void pal1(TStyle *style)
{
  const unsigned char Number = 6;
  Int_t colours[10];

  Double_t Red[Number]   =  {0.75, 0.75, 0.5, 0.5, 0.2, 0.2,};
  Double_t Green[Number] =  {1.0,  1.0,  1.0, 1.0, 1.0, 1.0 };
  Double_t Blue[Number]  =  {0.75, 0.75, 0.5, 0.5, 0.2, 0.2 };
  Double_t  Stops[Number] = {0.0,  0.5, 0.50001, 0.6, 0.6000001, 1.0};


  Int_t FI = TColor::CreateGradientColorTable(Number, Stops, Red, Green, Blue, 10);
  for (unsigned char ind = 0; ind < 10; ind ++)
    colours[ind] = FI + ind;
  style -> SetPalette(10, colours);
  style -> SetPaintTextFormat("2.2f");
  style -> SetOptStat(0);
}

TStyle "st2" is supposed to use the default Root palette. However, the example doesn’t work. What could I fix?

The palette are note stored By the style. Only one palette is available. To have several on the same plot you should use TExec,

In this example using TExec both histograms are drawn with the same palette:

void pal();
int palette()
{
  TExec * ex = new TExec("ex", "pal();");
  TH2 * h1 = new TH2F("h1", "h1", 2, -0.5, 1.5, 2, -0.5, 1.5);
  h1 -> Fill(0.0, 0.0, 2.0);
  h1 -> Fill(0.0, 1.0, 2.5);

  h1 -> Fill(1.0, 0.0, 0.5);
  h1 -> Fill(1.0, 1.0, 1.5);
  TCanvas * c1 = new TCanvas;
  h1 -> Draw("COLZ");
  ex -> Draw();
  h1 -> Draw("COLZSAME");
  TH2 * h2 = new TH2F("h2", "h2", 2, -0.5, 1.5, 2, -0.5, 1.5);
  h2 -> Fill(0.0, 0.0, 2.0);
  h2 -> Fill(0.0, 1.0, 2.5);
  h2 -> Fill(1.0, 0.0, 0.5);
  h2 -> Fill(1.0, 1.0, 1.5);
  TCanvas *c2 = new TCanvas;
  h2 -> Draw("COLZ");
  return 0;
}

void pal()
{
  const unsigned char Number = 6;
  Int_t colours[10];

  Double_t Red[Number]   =  {0.75, 0.75, 0.5, 0.5, 0.2, 0.2,};
  Double_t Green[Number] =  {1.0,  1.0,  1.0, 1.0, 1.0, 1.0 };
  Double_t Blue[Number]  =  {0.75, 0.75, 0.5, 0.5, 0.2, 0.2 };
  Double_t  Stops[Number] = {0.0,  0.5, 0.50001, 0.6, 0.6000001, 1.0};
  TColor::CreateGradientColorTable(Number, Stops, Red, Green, Blue, 10);
}

What is wrong?

grep -r TExec ${ROOTSYS}/tutorials

I study the example multipalette.C but I find no clue what is wrong in my example.