I’m creating a TRatioPlot
with a TH1F*
and a THStack
. I use SetOption("HIST")
on the TH1*
objects used to create the stack, but when I draw the TRatioPlot
the stack is drawn with error bars.
Is there a way of drawing the stack without error bars, without cloning it and drawing it explicitly on the top pad?
Try getting the upper pad of the TRatioPlot and from there retrieve the histo or stack and change its Draw option:
{
gStyle->SetOptStat(0);
auto C = new TCanvas("C", "A ratio example");
auto h1 = new TH1D("h1", "TRatioPlot Example; x; y", 50, 0, 10);
auto h2 = new TH1D("h2", "h2", 50, 0, 10);
auto f1 = new TF1("f1", "exp(- x/[0] )");
f1->SetParameter(0, 3);
h1->FillRandom("f1", 1900);
h2->FillRandom("f1", 2000);
h1->Sumw2();
h2->Scale(1.9 / 2.);
h2->SetLineColor(kRed);
// Create and draw the ratio plot
auto rp = new TRatioPlot(h1, h2);
C->SetTicks(0, 1);
rp->Draw();
rp->GetLowYaxis()->SetNdivisions(505);
rp->GetUpperPad()->cd();
// draw h2 without error bars:
gPad->GetListOfPrimitives()->FindObject(h2)->SetDrawOption("histo, same");
TLegend *legend = new TLegend(0.3, 0.7, 0.7, 0.85);
legend->AddEntry("h1", "First histogram", "l");
legend->AddEntry("h2", "Second histogram", "l");
legend->Draw();
}
This still doesn’t work for me. Using a THStack I get two problems I would like to solve: the points for h1 aren’t plotted on the upper pad and I can’t get rid of the errors on the stack plot.
Here’s a MWE:
void TRatioPlotStack()
{
gStyle->SetHistLineColor(kBlack);
gStyle->SetMarkerStyle(8);
gStyle->SetMarkerSize(0.7);
TGaxis::SetMaxDigits(3);
gROOT->ForceStyle();
gStyle->SetOptStat(0);
auto C = new TCanvas("C", "A ratio example");
auto h1 = new TH1D("h1", "TRatioPlot Example; x; y", 50, 0, 10);
auto h2 = new TH1D("h2", "h2", 50, 0, 10);
auto h3 = new TH1D("h3", "h3", 50, 0, 10);
auto f1 = new TF1("f1", "exp(- x/[0] )");
f1->SetParameter(0, 3);
for(int ii=0; ii<h1->GetXaxis()->GetNbins(); ii++) h1->SetBinContent(ii+1,150);
h2->FillRandom("f1", 2000);
h3->FillRandom("f1", 2000);
h1->Sumw2();
h1->SetOption("E");
h2->Scale(1. / 2.);
h2->SetFillColor(kRed);
h3->SetFillColor(kBlue);
THStack* st = new THStack("st","");
st->Add(h2);
st->Add(h3);
auto rp = new TRatioPlot(h1, st);
C->SetTicks(0, 1);
rp->Draw();
rp->GetLowYaxis()->SetNdivisions(505);
}
Looks like a possible bug in the TRatioPlot source code for this case (ratio TH1 to THStack).
With this example:
{
gStyle->SetHistLineColor(kBlack);
gStyle->SetMarkerStyle(8);
gStyle->SetMarkerSize(0.7);
TGaxis::SetMaxDigits(3);
gROOT->ForceStyle();
gStyle->SetOptStat(0);
auto h1 = new TH1D("h1", "h1; x; y", 50, 0, 10);
auto h2 = new TH1D("h2", "h2; x; y", 50, 0, 10);
auto h3 = new TH1D("h3", "h3; x; y", 50, 0, 10);
auto f1 = new TF1("f1", "exp(- x/[0] )");
f1->SetParameter(0, 3);
for(int ii=0; ii<h1->GetXaxis()->GetNbins(); ii++) h1->SetBinContent(ii+1,150);
h2->FillRandom("f1", 2000);
h3->FillRandom("f1", 2000);
h1->Sumw2();
//h1->SetOption("E");
h2->Scale(1. / 2.);
h2->SetFillColor(kRed);
h2->SetFillStyle(3365);
h3->SetFillColor(kBlue);
h3->SetFillStyle(3356);
THStack* st = new THStack("st","");
st->Add(h2,"histo");
st->Add(h3,"histo");
cout << endl << "/- - - - - Before:" << endl;
gROOT->ls();
auto C1 = new TCanvas("h1_st", "Ratio h1 to stack");
auto rp = new TRatioPlot(h1, st);
C1->SetTicks(0, 1);
rp->Draw();
rp->GetLowYaxis()->SetNdivisions(505);
rp->GetUpperPad()->cd();
//gPad->GetListOfPrimitives()->FindObject(st)->SetDrawOption("histo,same");
//gPad->GetListOfPrimitives()->FindObject(h2)->SetDrawOption("histo,same");
rp->GetUpperPad()->cd();
cout << endl << "/- - - - - Ratio h1, st:" << endl;
gPad->GetListOfPrimitives()->ls();
gPad->Modified();
gPad->Update();
auto C2 = new TCanvas("st_h1", "Ratio stack to h1");
auto rp2 = new TRatioPlot(st,h1);
C2->SetTicks(0, 1);
rp2->Draw();
rp2->GetLowYaxis()->SetNdivisions(505);
rp2->GetUpperPad()->cd();
gPad->GetListOfPrimitives()->FindObject(h1)->SetDrawOption("histo,same");
rp2->GetUpperPad()->cd();
cout << endl << "/- - - - - Ratio st, h1:" << endl;
gPad->GetListOfPrimitives()->ls();
gPad->Modified();
gPad->Update();
cout << endl << "/- - - - - Final:" << endl;
gROOT->ls();
cout << endl;
}
I get (on ROOT 6.36.02):
And this output:
/- - - - - Before:
OBJ: TH1D h1 h1 : 0 at: 0x63529530e020
OBJ: TH1D h2 h2 : 0 at: 0x635295a06190
OBJ: TH1D h3 h3 : 0 at: 0x635295671af0
/- - - - - Ratio h1, st:
OBJ: TList TList Doubly linked list : 0
TFrame X1= 0.000000 Y1=0.000000 X2=10.000000 Y2=212.625000
THStack Name= st Title= Option=
OBJ: TList TList Doubly linked list : 0
OBJ: TH1D h2 h2 : 0 at: 0x635295a06190
OBJ: TH1D h3 h3 : 0 at: 0x635295671af0
OBJ: TH1D h2 h2 : 0 at: 0x6352962dca60
/- - - - - Ratio st, h1:
OBJ: TList TList Doubly linked list : 0
THStack Name= st Title= Option=
OBJ: TList TList Doubly linked list : 0
OBJ: TH1D h2 h2 : 0 at: 0x635295a06190
OBJ: TH1D h3 h3 : 0 at: 0x635295671af0
OBJ: TH1D h1 h1 : 0 at: 0x63529530e020
/- - - - - Final:
OBJ: TH1D h1 h1 : 0 at: 0x63529530e020
OBJ: TH1D h2 h2 : 0 at: 0x635295a06190
OBJ: TH1D h3 h3 : 0 at: 0x635295671af0
OBJ: TH1D h2 h2 : 0 at: 0x6352962dca60
OBJ: TH1D h2 h2 : 0 at: 0x635296768e70
So, in h1/st, h1
is lost and replaced by an extra h2
(last listed object), which does not point to the actual h2
address (compare with the “before” list), and trying to get this h2
(uncommenting the line in my example) makes the code crash.
Maybe you can use the workaround suggested by @couet here (add the histos of the THStack yourself and then do a normal h1/h2 ratio):