Stats Box (TPaveStats) in PyRoot

I’m trying to edit the default location of a stats box for histograms. I haven’t found something that can go in the rootlogon.C so I figure I have to put it in my drawing script itself.

I’ve tried this, but get an error:

st = hist.FindObject("stats") st.SetX1NDC(0.65)
with the error:

Traceback (most recent call last): File "createHist.py", line 36, in <module> st.SetX1NDC(0.65) AttributeError: 'TObject' object has no attribute 'SetX1NDC'
What do I have to do in PyRoot to be able to set that?

Hi,

as long as the histogram has not been drawn, the stats object will be NULL. It’ll be a TPaveStats after hist.Draw().

AFAICS, that behavior is equivalent to .C:root [0] h = new TH1F() (class TH1F*)0x842c198 root [1] h.FindObject( "stats" ) (const class TObject*)0x0 root [2] h.Draw() <TCanvas::MakeDefCanvas>: created default TCanvas with name c1 root [3] h.FindObject( "stats" ) (const class TObject*)0x8678398 root [4]
Cheers,
Wim

Hi there,
I don’t know if the problem in this rather old post was resolved, but I am also having a problem moving the default position of TPaveStats. I can’t seem to retrieve the stats box.

I followed the previous advice in the post about ensuring that the histo is drawn first.
If I check that the stats box is in the list of functions :
hist.Draw(“sames”)
print hist.GetListOfFunctions()
print hist.GetListOfFunctions().FindObject(“stats”)

I get:
<ROOT.TList object (“TList”) at 0xa50f688>
<ROOT.TObject object at 0x(nil)>

If someone could help me to see my error that would be very much appreciated!
Many thanks
Sarah

Hi,

After the Draw, did you call gPad->Update(); to make sure the TPaveStats is created.

Philippe.

Hi Philippe,
ah yes that was the problem!
Sorry for the bother over what turned out to be a trivial problem, but thank you very much for replying.
Best regards
Sarah

One easy way that I couldn’t find posted anywhere and fortunately I remembered out of nothing is that it is possible to change python class by force.

That is, it is possible to do:

stats = hist.FindObject( "stats" ) if not stats: continue stats.__class__ = ROOT.TPaveStats

… then use stats as a TPaveStats.

Hi,

Which in the case of C++ bound objects is actually the same as a reinterpret_cast (the bound C++ object is referenced with a void* pointer and in use the type is picked up from the python proxy object, without further checks). Iow., can’t recommend that. I’m sitting on some patches that provide a proper cast() function, but have not had time to vet and check those in.

Beyond that, this:

will auto-cast to the actual object, so if the result is non-NULL, it will be of a TPaveStats type (or any derived type in the future). Iow., changing the class should not be needed, and if you do anyway, it may break (crash) in the future.

Cheers,
Wim