Problem with THStack::Draw("lego nostack") for TH2

Dear rooters.

I want to use THStack to draw a set of TH2 histograms on the same TPad, but found that THStack cannot be drawn properly with option “lego nostack”.

Here is an example:

{
  TCanvas *c1 = new TCanvas("c1","histogram example",200,10,700,500);
  TH1F* h1d  = new TH1F("h1d","py vs px",20,-2,2);
  TH2F* h2d  = new TH2F("h2d","py vs px",20,-2,2,20,-2,2);
  Float_t px, py;
  for ( Int_t i=0; i<25000; i++) {
     px = gRandom->Rndm();
     py = gRandom->Gaus();
     h2d->Fill(px,py,1);
     h1d->Fill(px,1);
     h1d->Fill(py,1);
  }

  THStack* stack1 = new THStack("stack1", "test stacked TH1F");
  THStack* stack2 = new THStack("stack2", "test stacked TH2F");
  c1->Divide(2,1);

  c1->cd(1);
  stack1->Add(h1d);
  stack1->Draw("nostack");

  c1->cd(2);
  stack2->Add(h2d);
  stack2->Draw("lego1 nostack");
}

I tried several ROOT versions: 5.14, 5.16 and 5.18. All have this problem.

–Shuwei[/code]

I do not understand why you put the option “nostack” … remove it and it will work.
stack2->Draw("lego1 ");

The example is shown for one histogram only. I need the option “nostack” to draw multiple histograms, which is what I want.

–Shuwei

nostack does not apply on lego. This option is meant to be used in the 1D case like in the following example:

{
  TCanvas *c1 = new TCanvas("c1","c1",800,600);

  TH1F *h1 = new TH1F("h1","Histo 1",100,-5,5);
  h1->FillRandom("gaus",10000);
  
  TF1* gaus = (TF1*)gROOT->FindObject("gaus");
  gaus->SetParameter(1,1.5);
  gaus->SetParameter(2,0.3);
  TH1F *h2 = new TH1F("h2","Histo 2",100,-5,5);
  h2->FillRandom("gaus",20000);
 
  h1->SetFillStyle(3004);
  h1->SetFillColor(1);
  h2->SetFillStyle(3005);
  h2->SetFillColor(1);

  THStack *hs = new THStack("hs","A stack of histograms");
  hs->Add(h1);
  hs->Add(h2);

  TLegend *leg = new TLegend(0.1,0.6,0.4,0.9);
  leg->AddEntry(h1,"h1","f");
  leg->AddEntry(h2,"h2","f");
  
  hs->SetTitle("THStack drawing with hatches");
  hs->Draw("nostack");
  leg->Draw();
}

In this example you can see that the 2 histograms are drawn in the same pad and that they may overlap. The overlap is not implemented in case of lego.

[quote]The overlap is not implemented in case of lego.[/quote]It is still not the case apparently (see the attached pics and code).
How about implementing it (TH2Stack)?

Something more useful might be to superimpose half transparent histograms (with zero bins not taken into account as it is done for hstack1 and hstack2 in the attached macro, see /viewtopic.php?t=4598).
Isn’t it already implemented somehow for GLplots or EVE?

TIA,
Z

PS : Depending on the output format (gif or png), the image’s not the same!
ztest.cpp (3.76 KB)




You are right, it is still not done. Did I say I will implement it ? it does not seems so. Not easy, not enough manpower and always something else to do. If you volunteer to do it you are welcome. :slight_smile:
A new class will not be of any help.
I’ll have an other look… but it can not promise anything soon.

[quote]PS : Depending on the output format (gif or png), the image’s not the same!
[/quote]
not for me …

Thanks for planning to give it a try Olivier :smiley:
If I find some time some day, I’ll let you know!

As for the image thing, using TCanvas *canvas = new TCanvas ("canvas") ; instead of

TCanvas *canvas = new TCanvas ("canvas","canvas",0,0,gClient->GetDisplayWidth(),gClient->GetDisplayHeight()) ; helps a bit.
Still… :frowning: (see the bottom right corner plot)
either on CentOS_5.5/ROOT_5.16.00b or on WinXP_Cygwin/ROOT_5.{27.02,26.00b,5.24.00}_bin.

Cheers,
Z




PS: How about the GL/EVE way?
What do Timur and Matevz reckon?

Do gPad->Update() before saving the canvas.

[quote]PS: How about the GL/EVE way?
What do Timur and Matevz reckon?[/quote]
Transparency is needed for the kind of representation your are asking.
THStack cannot be be represent using GL right now. I’ll will point this post to Timur.

[quote]Do gPad->Update() before saving the canvas.[/quote] Thx!
The issue remains as soon as the canvas width exceeds the screen width (which is the case whilst calling gClient->GetDisplayHeight())

[quote]THStack cannot be be represent using GL right now. I’ll will point this post to Timur.[/quote]What about (plain) TH2?
(like in root.cern.ch/drupal/sites/defaul … ego-3d.png with transparency and a nostack-like feature)

Cheers,
Z

The picture you pointed too is what we call a THStack, a collection of TH2s.

Yep but they are plotted in a EVE window (with an intriguing GLViewer tab…)
Maybe something close enough already exists…
Cheers,
Z

No.
You can try:

[code]{
gStyle->SetCanvasPreferGL(true);
Int_t n = 39;
Int_t nb = 7;
TH2D *hist[n];
THStack *a = new THStack(“a”,“LegoPlot”);

    for(Int_t ihist=0; ihist<n; ihist++ ) {
          TString hn="hist_"; hn+=ihist;
          hist[ihist] = new TH2D(hn,hn,nb,0,nb,10,0,10);
          hist[ihist]->SetBinContent(ihist+1,ihist,double(ihist));
          hist[ihist]->SetBinContent(ihist  ,ihist,double(ihist));
          hist[ihist]->SetBinContent(ihist-1,ihist,double(ihist));
          hist[ihist]->SetFillColor(ihist);
          a->Add(hist[ihist]);
    }
    a->Draw("LEGO1 GL"); 

}
[/code]
But it does not do anything special with transparency.

[quote=“Zesp”]Yep but they are plotted in a EVE window (with an intriguing GLViewer tab…)
Maybe something close enough already exists…
Cheers,
Z[/quote]

I think, I can implement stack for TH2 hists in GL. I remember I was going to do this, but something stupid and very annoying stopped me - may be was the fact that histogramms in a THStack can have different and even non-overlapping ranges, may be something else and I cancelled thglstack.

Thanks guys.

Olivier, in your macro, I don’t see the point of using gStyle->SetCanvasPreferGL(true).
Attached’s the only non-stack way I see to superimpose TH2s for the time being.
(Note that adding one white empty histogram to the THStack is enough to visually remove non-zero bins, see /viewtopic.php?t=4598)

Timur, could you please implement the “same binning case” as a start (with no-stack & transparency features) [-o<

Cheers,
Z
ztest.cpp (2.7 KB)

Forget my macro, the main point of it was to show that what you asked is not implemented.

Timur, did you have time to give it a try so far?
Cheers,
Z

[quote=“Zesp”]Timur, did you have time to give it a try so far?
Cheers,
Z[/quote]

Hi.

You are lucky, I tried it today. I had a look into THStack::Paint and remembered what was the real problem - it’s not an axis range. THStack draws histogramms using TH1(2)::Paint(“samexxxx”) option. So, each histogramm painter does not know the context. This is ok for 1D hist, this is already bad for 2D hist. See my pictures, with and without transparency.

I’ve solved similar problem for TH3, but this solution was criticized severely by Rene as “ad-hoc” and non-general. In principle, we can change THStack::Paint for the case the number of dimensions is bigger than 1 and pass the list of histogramms into painter directly (with gl/non-gl implementations for stack).