Get color id used for the histogram with the "PLC" option

Hi!

I use some colour palette:
gStyle -> SetPalette(kDarkRainBow);

Then I draw several histograms in a loop:

  for(int itHist = 0; itHist < vHist.size(); ++itHist){
    vHist[itHist] -> Draw("hist L PLC same");
  }

How I can now get the colours assigned to each of these histograms to reuse them later?
vHist[itHist] -> GetLineColor(); (after drawing) returns always the colour number 602 which is obviously wrong.

Hi,

is vHist an array of TH1s or TH2s?

Hi,

It’s an array (vector) of TH1:

vector<TH1D *> vHist;

I can’t reproduce it with the code I post below. Can you please provide a minimal reproducer?

        vector<TH1D *> vHist;
        TH1D* h0 = new TH1D("h0", "Title;X;Y", 10, 0., 10.);
        TH1D* h1 = new TH1D("h1", "Title;X;Y", 10, 0., 10.);
        TH1D* h2 = new TH1D("h2", "Title;X;Y", 10, 0., 10.);

        h0->SetLineColor(2);
        h1->SetLineColor(3);
        h2->SetLineColor(4);

        vHist.push_back(h0);
        vHist.push_back(h1);
        vHist.push_back(h2);

        vHist.at(0)->Draw("hist PLC");
        vHist.at(1)->Draw("hist PLC same");
        vHist.at(2)->Draw("hist PLC same");

        for (short i=0; i<vHist.size(); ++i)
                printf("The histogram with index #%i is drawn with color #%i\n", i, vHist.at(i)->GetLineColor());

        return;

1 Like

Working example:

void test(){
  TCanvas* canvas = new TCanvas("canvas");
  TH1F * frame = canvas -> DrawFrame(0, 0, 10, 10);

  vector<TH1D *> vHist;
  for(int itHist = 0; itHist < 5; ++itHist){
      TH1D *hist = new TH1D(Form("h%d", itHist), "", 10, 0., 10.);
      vHist.push_back(hist);
  }

  for(int itHist = 0; itHist < vHist.size(); itHist++){
    vHist[itHist] -> Draw("hist L PLC same");
    printf("%d\n", vHist[itHist] -> GetLineColor());
  }
}

The output:

Processing test.C...
602
602
602
602
602
1 Like

See also:

Thank you.

So, right now I can get all colours from palette this way:
auto paletteColours = TColor::GetPalette();
The size is 255 elements, so I can do some simple math and select corresponding colour by paletteColours.At() at even intervals – but why GetLineColor() does not work?

It works:

root [0] auto h = new TH1F("h","h",10,0,1)
root [1] h->Draw("PLC")
root [2] h->GetLineColor()
(short) 924
root [3] 

No, it does not. You can add these lines to your ROOT session:

root [3] auto h2 = new TH1F("h2","h",10,0,1)
root [4] h2->Draw("PLC same")
root [5] h2->GetLineColor()

And get again

(short) 924

When the option PLC is passed to TH1::Draw() a color index id is picked inside the current color palette and SetLineColor with that color index id is called. Therefore if you call GetLineColor just after you find the color index that was just set. But if you come later in another ROOT session and, for instance, omit to call SetPalette with the same palette (in your case RainBow) the color index id will not point to the same color.

Please, see my working example in some previous post: 5 histograms are drawn on the same canvas simultaneously one after another with the “PLC same” option, and they are drawn with different line colours. But the colour id returned by the GetLineColor() is the same.

I can call GetLineColor() right after drawing too and get the same id’s:

void test(){
  gStyle -> SetPalette(kDarkRainBow);
  TCanvas* canvas = new TCanvas("canvas");
  TH1F * frame = canvas -> DrawFrame(0, 0, 10, 10);

  vector<TH1D *> vHist;
  for(int itHist = 0; itHist < 5; ++itHist){
    TH1D *hist = new TH1D(Form("h%d", itHist), "", 10, 0., 10.);
    vHist.push_back(hist);
    vHist[itHist] -> Draw("hist L PLC same");
    printf("%d\n", vHist[itHist] -> GetLineColor());
  }
}
Processing test.C...
602
602
602
602
602

What exactly is wrong with this code?

  gStyle -> SetPalette(kDarkRainBow);
  TCanvas* canvas = new TCanvas("canvas");
  TH1F * frame = canvas -> DrawFrame(0, 0, 10, 10);

  vector<TH1D *> vHist;
  for(int itHist = 0; itHist < 5; ++itHist){
    TH1D *hist = new TH1D(Form("h%d", itHist), "", 10, 0., 10.);
    hist->SetLineColor(itHist+1);
    vHist.push_back(hist);
    vHist[itHist] -> Draw("hist L PLC same");
    printf("%d\n", vHist[itHist] -> GetLineColor());
  }

It prints out

1
2
3
4
5

just as it should.

This does not correspond to the drawn colour. The “PLC” option choose the line colour automatically.

As the color indices are equally distributed on the color map they can be computed only at painting time when all the objects stored in the current pad are in place. Therefore, in a macro, after a gPad->Update():

{
  TCanvas* canvas = new TCanvas("canvas");
  gStyle -> SetPalette(kDarkRainBow);
  TH1F * frame = canvas -> DrawFrame(0, 0, 10, 10);

  vector<TH1D *> vHist;
  for(int itHist = 0; itHist < 5; ++itHist){
    TH1D *hist = new TH1D(Form("h%d", itHist), "", 10, 0., 10.);
    vHist.push_back(hist);
    vHist[itHist] -> Draw("hist L PLC same");
  }
  gPad->Update();
  for (int i=0; i<5; i++) printf("%d\n", vHist[i] -> GetLineColor());
}

This macro gives:

root [0]
Processing test.C...
1179
1242
1305
1368
1431
root [1]

Thank you.
But I need to know the indices after first n histograms are drawn to reuse them later on other m packets by n histograms (now with SetLineColor() and with different line styles).
So, there is no any solution other than in Get color id used for the histogram with the "PLC" option - #7 by vkireyeu ?

The number of objects that will be put/drawn in the pad with the drawing option PLC is not known in advance. It is known only at painting time when all the objects are drawn (see the difference between Draw and Paint). So after you have painted (with gPad->Update()) the first n histograms you can retrieve the indices and use them on another set of histograms.

Okay, thank you!

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