TFile *herwig = new TFile(“HadronicMultiplicity_eneEtaDep_J8_Herwig_120x.root”);
TFile *pythia = new TFile(“HadronicMultiplicity_eneEtaDep_J8_Pythia_120x.root”);
the stats box for the second histogram does not move. How can I move it? Is the way I do it the best way or there is an easier way (not dragging with the mouse as I want to automate making lots of plots in my macro to save time when redoing them)?
Hello Mark,
I am using using PyROOT, so my situation could be a little different from yours…
Anyway, in my case the TPaveStats for the second histogram (the one
drawn with the “same” option) doesn’t even show up. If I try to access it via
TH1F::GetListOfFunctions().FindObject(“stats”) I get a null pointer.
So I guess that, as you are accessing it via TCanvas::GetPrimitive(“stats”),
you are still reading the one from the first histo that you drawn.
The workaround that I found is:
histo1.Draw()
c1.GetPad(index+1).Update()
stats1 = histo1.GetListOfFunctions().FindObject("stats").Clone("stats1")
stats1.SetY1NDC(.5)
stats1.SetY2NDC(.7)
histo2.Draw()
c1.GetPad(index+1).Update()
stats2 = histo2.GetListOfFunctions().FindObject("stats").Clone("stats2")
# move stats2 where you want it to be
histo1.Draw("same")
stats1.Draw()
stats2.Draw()
You should translate this from python into C, if you want.
I hope this helps. Cheers,
Hello,Rene,
I test your code and works fine. The only thing I could’t understand is if I don’t set the name as :
stats->SetName(“h1stats”);
stats2->SetName(“h1stats2”);
Then the moving and color doesn’t work.
In my opinion, SetName is just set a name for a object.
What’s the ranson for this?
Many thanks.
When you want to superimpose a second TPaveStats to the same picture, it is important to change the name of an already existing TPaveStats, otherwise it will be deleted. This is is fundamental when redrawing again and again the histogram with many stats boxes.
Hi,
I have the same problem with PaveStats when looping over histograms. Within the loop over a list of TH1F, I call this following function
void DrawStatBox(TH1Fh1, int i){
gPad->Update();
TPaveStats stat;
stat = (TPaveStats)h1->GetListOfFunctions()->FindObject(“stats”);
stat->SetName(sampleName[i].c_str());
stat->SetY1NDC(stat->GetY1NDC()-i0.2);
stat->SetY2NDC(stat->GetY2NDC()-i*0.2);
stat->SetTextColor(colors[i]);
//stat->SetOptStat(11);//??? not working???
stat->Draw();
}
I would like to draw all histograms superimposed with the corresponding stat boxes in different positions and colors. The result of the loop is that all the stat boxes are drawn correctly but contain the same information, i.e. only the info of the last stats is saved and plotted.
Can you help me?
// http://root.cern.ch/root/html/TStyle.html#TStyle:SetOptStat
gStyle->SetOptStat(1111);
// ...
// http://root.cern.ch/root/html/TH1.html#TH1:SetStats
// SomeHisto->SetStats(kTRUE);
// ...
// http://root.cern.ch/root/html/THistPainter.html
SomeHisto->Draw("SAMES"); // you MUST draw "SomeHisto" first (e.g. with "SAMES")
gPad->Modified(); gPad->Update(); // make sure it's really (re)drawn
// http://root.cern.ch/root/html/TPaveStats.html
#if 1 /* 0 or 1 */
TPaveStats *s = ((TPaveStats*)(SomeHisto->FindObject("stats")));
// if (s) s->SetName("SomeDistinctObjectName"); // you can rename "stats" if you want
#else /* 0 or 1 */
TPaveStats *s = ((TPaveStats*)(gPad->GetPrimitive("stats")));
if (s) s->SetName("SomeDistinctObjectName"); // you MUST rename "stats"
#endif /* 0 or 1 */
if (s) {
s->SetTextColor(SomeColorIndex);
s->SetX1NDC(LeftX);
s->SetX2NDC(RightX);
s->SetY1NDC(BottomY);
s->SetY2NDC(TopY);
}
gPad->Modified(); gPad->Update(); // make sure it's really (re)drawn
all the suggestions you gave me are already implemented. Then I discovered that the problem comes from the fact that I draw the histograms normalized with TH1F::DrawNormalized(), which causes the stat box of the first histogram to be replaced by the following one (even changing the name of the PaveStats). When I use simple TH1F:Draw() everything works fine. Can you check if it’s true and give me a suggestion on how to overcome this limit? Thanks a lot, cheers
francesca
// http://root.cern.ch/root/html/TStyle.html#TStyle:SetOptStat
gStyle->SetOptStat(1111);
// ...
TH1 *h; // a pointer to the drawn histogram
TPaveStats *s; // a pointer to the statistics box
// ...
// ... for every "Histogram" that you want to process ...
// ...
// http://root.cern.ch/root/html/TH1.html#TH1:SetStats
// Histogram->SetStats(kTRUE);
// ...
// you MUST draw your "Histogram" first (e.g. with "SAMES") ...
// http://root.cern.ch/root/html/THistPainter.html
#if 0 /* 0 or 1 */
// http://root.cern.ch/root/html/TH1.html#TH1:Draw
Histogram->Draw("SAMES"); // TH1::Draw
h = Histogram;
#else /* 0 or 1 */
// http://root.cern.ch/root/html/TH1.html#TH1:DrawCopy
// h = Histogram->DrawCopy("SAMES"); // TH1::DrawCopy
// http://root.cern.ch/root/html/TH1.html#TH1:DrawNormalized
h = Histogram->DrawNormalized("SAMES"); // TH1::DrawNormalized
#endif /* 0 or 1 */
gPad->Modified(); gPad->Update(); // make sure it's really (re)drawn
// ... and now you can retrieve and modify the "stats" TPaveStats
// http://root.cern.ch/root/html/TPaveStats.html
#if 1 /* 0 or 1 */
s = ((TPaveStats*)(h->FindObject("stats")));
// if (s) s->SetName("SomeDistinctObjectName"); // you can rename "stats" if you want
#else /* 0 or 1 */
s = ((TPaveStats*)(gPad->GetPrimitive("stats")));
if (s) s->SetName("SomeDistinctObjectName"); // you MUST rename "stats"
#endif /* 0 or 1 */
if (s) {
s->SetTextColor(SomeColorIndex);
s->SetX1NDC(LeftX);
s->SetX2NDC(RightX);
s->SetY1NDC(BottomY);
s->SetY2NDC(TopY);
}
gPad->Modified(); gPad->Update(); // make sure it's really (re)drawn
Hi,
ok so the trick is that I have to Draw (or DrawNormalized) the first TH in the loop twice… First Draw() it and then Draw(“SAMES”). Is this a bug or I’ve missed something? Thanks again, cheers
francesca
When I say that you must draw the histogram first, it means that you need to do it (either Draw or DrawCopy or DrawNormalized it) BEFORE you can get its “stats” TPaveStats (as shown in my example source code).
Usually, you need to draw the first histogram WITHOUT the “SAMES” option (in this case it will clear the current pad before drawing and then it will create and paint axes together with the histogram itself and its “stats”), while the remaining histograms will be drawn WITH the “SAMES” option (in the same pad).
You can also draw the first histogram twice. The first time just with the “AXIS” option (draws only axes), then again with “SAMES”.
Hi, this is actually what I was doing since the beginning, of course.
You said redraw so I interpret as drawing it twice. In any case this let me understand the problem.
In my code, I’m doing the update of the gPad (gPad->Modified(); gPad->Update(); ) after drawing the histogram, as explained in the documentation of the TPaveStats, and then get the TPaveStats and draw it. Differently your example includes a second update of the gPad after drawing the statbox. This second one is crucial, while with h1->FindObject("stats”) the first one is useless.
So the statbox needs to be included in the pad before drawing other statboxes, otherwise is overwritten.
(PS: with Draw and DrawNormalized there are different behaviors probably for a different memory allocation).
Note: in my example source codes, I never explicitly draw any statistics box myself. I simply make sure that the current pad is “redrawn” (“updated”) in relevant places. In particular, updating the current pad after drawing the histogram and before retrieving its “stats” TPaveStats is MANDATORY.