Repositioning Stat Box for a Fit to TMultiGraph

Hello All,

I am trying to figure out how to move the stat box for for a fit to a TMultiGraph plot. The following is my attempt:

        gStyle->SetOptFit(1);
        TMultiGraph* multiGraph5 = new TMultiGraph();
        multiGraph5->SetTitle("p2 of Double Gaussian Fit for n_{sigma,TOF}(e); Avg. Eta Bin; p4 of Double Gaussian Fit");
        multiGraph5->SetMinimum(0.8); // Set the minimum y axis value
        multiGraph5->SetMaximum(1.); // Set the maximum y axis value
        // :
        // Populated a few TGraphError objects with the needed data
        // :
        // Add all TGraphError to multiGraph
        multiGraph5->Add(p4Graph1);
        multiGraph5->Add(p4Graph2);
        multiGraph5->Add(p4Graph3);
        multiGraph5->Add(p4Graph4);
        multiGraph5->Add(p4Graph5);
        multiGraph5->Add(p4Graph6);

        // Do the fitting
        TF1* poly0 = new TF1("poly0", "pol0", -0.88, 1.2);
        multiGraph5->Fit("poly0", "R");
        multiGraph5->Draw("AP");

        c1->Update();
        TPaveText* st = (TPaveText*)multiGraph5->GetListOfFunctions()->FindObject("stats");
        st->SetX1NDC(.15);
        st->SetX2NDC(.5);
        c1->Modified();

But that gives me the following error:

Error: illegal pointer to class object st 0x0 1021  plot_read2EePairTree.C:1043:
*** Interpreter error recovered ***

My final goal is to be able to have two fits to the data on the same plot. But, to do that, I would need to be able to move the stat boxes because they would be overlayed on top of each other. So far, I have not been able to reposition a stat box for a single fit. Any help would be greatly appreciated!

Thank you very much!

Try

        TPaveStats* st = (TPaveStats*)multiGraph5->FindObject("stats");
        if (!st) { cout << "stats not found!\n"; return; }

Thank you very much for the reply @dastudillo! I tried your suggestion, and it returned “stats not found!” So, somehow, it is not finding the stat box object. Any thoughts on why that might be?

Try:

gPad->Modified(); gPad->Update();
TPaveStats *st = (TPaveStats*)gPad->GetPrimitive("stats");

Thanks for the reply! I tried the your suggestion in the following, but it still returned a null pointer for st:

        gStyle->SetOptFit(1);
        TMultiGraph* multiGraph5 = new TMultiGraph();
        multiGraph5->SetTitle("p2 of Double Gaussian Fit for n_{sigma,TOF}(e); Avg. Eta Bin; p4 of Double Gaussian Fit");
        multiGraph5->SetMinimum(0.8); // Set the minimum y axis value
        multiGraph5->SetMaximum(1.); // Set the maximum y axis value
        // :
        // Populated a few TGraphError objects with the needed data
        // :
        // Add all TGraphError to multiGraph
        multiGraph5->Add(p4Graph1);
        multiGraph5->Add(p4Graph2);
        multiGraph5->Add(p4Graph3);
        multiGraph5->Add(p4Graph4);
        multiGraph5->Add(p4Graph5);
        multiGraph5->Add(p4Graph6);

        // Do the fitting
        TF1* poly0 = new TF1("poly0", "pol0", -0.88, 1.2);
        multiGraph5->Fit("poly0", "R");
        multiGraph5->Draw("AP");
        multiGraph5->GetYaxis()->SetTitleOffset(1.3);
        multiGraph5->GetYaxis()->CenterTitle(true);

        gPad->Modified();
        gPad->Update();

        TPaveStats *st = (TPaveStats*)gPad->GetPrimitive("stats");
        if (!st) { cout << "stats not found!\n"; return; }

Try: gPad->ls();

Hi @Wile_E_Coyote! I tried your suggestion and here is what I got back. It looks like that there is a TPaveText object.

Canvas Name=c1 Title= Option=
 TCanvas fXlowNDC=0 fYlowNDC=0 fWNDC=1 fHNDC=1 Name= c1 Title=  Option=
  OBJ: TList	TList	Doubly linked list : 0
   TFrame  X1= -0.973000 Y1=0.000000 X2=1.293000 Y2=1.000000
   OBJ: TMultiGraph		p4 of Double Gaussian Fit for n_{sigma,TOF}(e); Avg. Eta Bin; p4 of Double Gaussian Fit : 0 at: 0x12d9a9a0
   OBJ: TPaveText	title  	X1= -1.227925 Y1=1.013877 X2=0.574619 Y2=1.118750

Try: multiGraph5->GetListOfFunctions()->ls();

The result of multiGraph5->GetListOfFunctions()->ls(); is the following:

OBJ: TList	TList	Doubly linked list : 0
 OBJ: TF1	poly0	pol0 : 0 at: 0x12610148

As you can see, there is no “stats” anywhere.

You could also try:
multiGraph5->GetHistogram()->GetListOfFunctions()->ls();

That’s interesting! Attached is the outcome of my code. Is there a way to access the stat box seen in the plot to change some of its settings? Let’s say, the color of the text.

Just to make sure … did you execute “gPad->Modified(); gPad->Update();” before you tried these various “ls()” commands?

Yeah! These ls() statements were after the following:

        gPad->Modified();
        gPad->Update();

Are you doing anything between these

        // Do the fitting
        TF1* poly0 = new TF1("poly0", "pol0", -0.88, 1.2);
        multiGraph5->Fit("poly0", "R");
        multiGraph5->Draw("AP");
        multiGraph5->GetYaxis()->SetTitleOffset(1.3);
        multiGraph5->GetYaxis()->CenterTitle(true);

and these

        gPad->Modified();
        gPad->Update();

(and gPad->ls())?
Maybe you are doing something else that you are not showing us and is affecting the outcome?
If you stop your code (add return;) right here

        multiGraph5->Fit("poly0", "R");
        multiGraph5->Draw("AP");
        return;

is the fit stats box shown in the canvas?
By the way, graph->Fit already draws the graph with the “AP” options, so you don’t need to do graph->Draw("AP") after that --unless, of course, you use other draw options.

@dastudillo Thank you very much for your reply! Yes, the portion of code that I show is only a small fraction of a much larger macro that produces 10’s of histograms. It could be very well that there are other parts of my code that have impact on what I am trying to accomplish in the portion I posted here.

I appreciate the help of everyone here! I decided to focus on other things since moving the stat box was not a top priority. Thank you very much for your help!

The stats are stored in the last graph:

{
   TCanvas *c = new TCanvas();
   gStyle->SetOptFit(1111);
   TGraph *g[3];
   Double_t x[10] = {0,1,2,3,4,5,6,7,8,9};
   Double_t y[10] = {1,2,3,4,5,5,4,3,2,1};
   TMultiGraph *mg = new TMultiGraph();
   for (int i=0; i<3; i++) {
      g[i] = new TGraph(10, x, y);
      for (int j=0; j<10; j++) y[j] = y[j]-1;
      mg->Add(g[i]);
   }
   mg->Draw("a*l");
   mg->Fit("gaus");

   gPad->Modified();
   gPad->Update();
   st = (TPaveStats*)g[2]->GetListOfFunctions()->FindObject("stats");
   if (!st) { cout << "stats not found!\n"; return;}
   st->SetX1NDC(0.4);
   st->SetX2NDC(0.6);
   st->SetY1NDC(0.2);
   st->SetY2NDC(0.4);
   gPad->Modified();
   gPad->Update();
}

1 Like