Using TPaveStats in PyROOT and moving the stat box

Hi Rooters,

sorry for disturbing. I have some problem translating CPP to Python, moreover I cannot find pyroot tutorials much useful for my problem, neighter in other forum’s posts. So, my problem is that I would like to use the TPaveStats class to create a box with statistics and moving it where I want. At the moment I just used the gstyle method and yes, it works but it covers part of the plot.
Here is the code:

func = ROOT.TF1('func', 'exp([0]*x)',0, np.amax(mean_s))


g = TGraphErrors(index, volt,  mean_s, x_err, std_s)
g.SetName('sipm averaged count')
g.SetTitle('sipm averaged count')
g.SetMarkerStyle(8)
g.SetMarkerColor(1)
g.GetYaxis().SetTitle("count");
g.GetXaxis().SetTitle("385 nm Light Voltage supply [V]");
g.Fit('expo')
#g.Fit('pol2', "EX0")
gStyle.SetOptFit(1)
g.Draw("AP")
c1.SaveAs(pdffile)


As you could see I also tried to simply make a custom exponential function but i failed as the fit…well, doesn’t fit.
I will attach some plot just to show.

I think I don’t have to explain which images is showing what…
Anyway, so, please, help me:
a) Using TPaveStats or Text to move the box elsewhere (maybe also adding the complete fitting function exp(p0+p1*x))
b) Understand why my custom function is not working

Thanks in advance!


_ROOT Version: 6.20.04
Platform: Ubuntu 16.04
Compiler: gcc 5.4.0


Hi,

@couet do you know how he can use TPaveStats to create a box with statistics and move it where he wants?

As for the custom function you define (func) you are not really using it in the Fit call, are you? You should do g.Fit(func).

see how to move the stats here: https://root.cern/doc/master/transpad_8C.html

Hi etejedor,
actually it is not showed in the code, but yes, I tried with

fit = g.Fit(‘func’)
gStyle.SetOptFit(1)
g.Draw(“AP”)

but the result is what you see in the second image.

@moneta can you think of why the fit gives the result in the second image?

The function he is using is
func = ROOT.TF1('func', 'exp([0]*x)',0, np.amax(mean_s))

Hi,
There could be various reasons, I would need to have the data and try to understand the exact cause. Most likely you are starting with parameter values too far away from the minimum solution. I would try with better initial values

Lorenzo

Ok thanks!
I will try! I guessed it could be related to data!

Ok
I tried this:

c1 = TCanvas('c1','c1',1400,800)
pad1 = TPad("pad1","pad1",0,0,1,1);
pad1.Draw()
pad1.cd()
g = TGraphErrors(index, volt,  mean_s, x_err, std_s)
g.SetName('sipm averaged count')
g.SetTitle('sipm averaged count')
g.SetMarkerStyle(8)
g.SetMarkerColor(1)
g.GetYaxis().SetTitle("count");
g.GetXaxis().SetTitle("385 nm Light Voltage supply [V]");
g.Fit('expo')
g.Draw("AP")
pad1.Update()
st = g.FindObject("stats") 
st.SetX1NDC(0.)
st.SetX2NDC(0.3)
pad1.Modified();
c1.cd();

and I get this error:

Traceback (most recent call last):
  File "sensori.py", line 93, in <module>
    st.SetX1NDC(0.4)
AttributeError: 'TObject' object has no attribute 'SetX1NDC'

Also if I try something like:

st = TPaveStats (g.GetListOfFunctions().FindObject(“stats”))

I get another error:

Traceback (most recent call last):
  File "sensori.py", line 93, in <module>
    st = TPaveStats (g.GetListOfFunctions().FindObject("stats"))
TypeError: none of the 3 overloaded methods succeeded. Full details:
  TPaveStats::TPaveStats() =>
    takes at most 0 arguments (1 given)
  TPaveStats::TPaveStats(const TPaveStats&) =>
    could not convert argument 1
  TPaveStats::TPaveStats(double x1, double y1, double x2, double y2, const char* option = "br") =>
    takes at least 4 arguments (1 given)

which I think is not related to the Pad itself…
Moreover If I try to print out g.GetListOfFunctions().FindObject("stats") I get a segmentation violation.

Hi,

It seems there is no object stats in g. When you do g.FindObject("stats") that must be returning a Python proxy that points to null, you can check it by doing print(st).

As for the reason why such stats are not there, perhaps @couet or @moneta can comment.

Hi,

The Graph classes do not have a TPaveStats object by default. You need to call
gStyle->SetOptFit(1) to have the fit parameters displayed.
In that case the "stats" object will be available in g.GetListOfFunctions()

Lorenzo

Related to the custom fit problem…I cannot explain several things.
I have a logarithmic function as follow:

When I tried to fit with this custon function:

func = ROOT.TF1(‘func’, ‘log(x -[0])’,2.88, np.amax(volt_fi))

I get again something completely wrong:


This time I will give data:
y = [32.66795367, 40.2639504, 68.87797903, 90.12073733, 172.39425837,
220.00927644, 293.72761905, 324.0, 355.01453488, 382.77651515,
407.74045802, 430.16332378, 449.74395161, 566.93831776, 629.10422535,
669.07488152, 697.36669785, 718.35962441, 734.11913696, 745.43913858,
752.2055814, 758.13857678]

x = [2.798, 2.864, 2.908, 2.919, 2.952, 2.971, 2.985, 3.0, 3.015, 3.03, 3.045, 3.06, 3.075, 3.22, 3.37, 3.52, 3.67, 3.82, 3.97, 4.12, 4.27, 4.42]

Moreover, considering the first exponential fit i showed you before (very first image), it happens also if I try to use a predefined function but changing the range as:

func1 = ROOT.TF1(‘func1’, ‘exp([0]+[1]*x)’,2.78, 2.96)

Always something like y=c…

Could someone explain me what is happening and if there could be another way to select just a sub-range for fit?
Thanks again.

Hi,
You need to set initial parameter values before fitting using

func.SetParameters(parameter_values)

The parameters need to be as close as possible to the best ones

Lorenzo

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