TPaveStat null access

Hi, I’m trying to add several stat boxes on one pad, but I kept getting null pointer issue when trying to find the stat object, even after I did gPad->Update() after drawing histogram. Any idea what is missing? Thanks in advance

Here is the piece of code that failed my test root .x test.cc:

void test(){

   TCanvas * c =  new TCanvas("c", "c", 800, 800);
   TH1F* h1 = new TH1F("h1", "h1", 10, 0, 10);
   TH1F* h2 = new TH1F("h2", "h2", 10, 0, 10);

   h1->Fill(4);
   h2->Fill(6);

   TPad *pad1 = new TPad("pad1", "pad1", 0, 0.3, 1, 1.0);
   pad1->Draw();
   pad1->cd();

   h1->Draw();
   pad1->Update();
   TPaveStats *st1 = (TPaveStats*)h1->FindObject("stats");
   st1->SetName("MC");
   st1->SetX1NDC(0.6);
   st1->SetX2NDC(0.9);
   st1->SetY1NDC(0.3);
   st1->SetY2NDC(0.6);


   h2->Draw("same");
   pad1->Update();
   TPaveStats *st2 = (TPaveStats*)h2->FindObject("stats");
   st2->SetName("Data");
   st2->SetX1NDC(0.6);
   st2->SetX2NDC(0.9);
   st2->SetY1NDC(0.6);
   st2->SetY2NDC(0.9);

}

ROOT Version: 6.24/04
Platform: Darwin 20.6.0 Darwin Kernel Version 20.6.0: Mon Aug 30 06:12:21 PDT 2021; root:xnu-7195.141.6~3/RELEASE_X86_64 x86_64
Compiler: Not Provided


Welcome to the ROOT Forum! Try with:

TPaveStats *st1 = (TPaveStats*)h1->GetListOfFunctions()->FindObject("stats");
...
TPaveStats *st2 = (TPaveStats*)h2->GetListOfFunctions()->FindObject("stats");

Hi @bellenot, thank you for the quick reply. I tried the suggestion but still get same errors:

Processing test.cc...
[/usr/local/Cellar/root/6.24.04/lib/root/libCling.so] cling_runtime_internal_throwIfInvalidPointer (no debug info)
[<unknown binary>] (no debug info)
[<unknown binary>] (no debug info)
[/usr/local/Cellar/root/6.24.04/lib/root/libCling.so] cling::IncrementalExecutor::executeWrapper(llvm::StringRef, cling::Value*) const (no debug info)
[/usr/local/Cellar/root/6.24.04/lib/root/libCling.so] cling::Interpreter::RunFunction(clang::FunctionDecl const*, cling::Value*) (no debug info)
[/usr/local/Cellar/root/6.24.04/lib/root/libCling.so] cling::Interpreter::EvaluateInternal(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, cling::CompilationOptions, cling::Value*, cling::Transaction**, unsigned long) (no debug info)
[/usr/local/Cellar/root/6.24.04/lib/root/libCling.so] cling::MetaSema::actOnxCommand(llvm::StringRef, llvm::StringRef, cling::Value*) (no debug info)
[/usr/local/Cellar/root/6.24.04/lib/root/libCling.so] cling::MetaParser::isXCommand(cling::MetaSema::ActionResult&, cling::Value*) (no debug info)
[/usr/local/Cellar/root/6.24.04/lib/root/libCling.so] cling::MetaParser::isCommand(cling::MetaSema::ActionResult&, cling::Value*) (no debug info)
[/usr/local/Cellar/root/6.24.04/lib/root/libCling.so] cling::MetaProcessor::process(llvm::StringRef, cling::Interpreter::CompilationResult&, cling::Value*, bool) (no debug info)
[/usr/local/Cellar/root/6.24.04/lib/root/libCling.so] HandleInterpreterException(cling::MetaProcessor*, char const*, cling::Interpreter::CompilationResult&, cling::Value*) (no debug info)
[/usr/local/Cellar/root/6.24.04/lib/root/libCling.so] TCling::ProcessLine(char const*, TInterpreter::EErrorCode*) (no debug info)
[/usr/local/Cellar/root/6.24.04/lib/root/libCling.so] TCling::ProcessLineSynch(char const*, TInterpreter::EErrorCode*) (no debug info)
[/usr/local/Cellar/root/6.24.04/lib/root/libCore.so] TApplication::ExecuteFile(char const*, int*, bool) (no debug info)
[/usr/local/Cellar/root/6.24.04/lib/root/libRint.so] TRint::ProcessLineNr(char const*, char const*, int*) (no debug info)
[/usr/local/Cellar/root/6.24.04/lib/root/libRint.so] TRint::Run(bool) (no debug info)
[/usr/local/Cellar/root/6.24.04/bin/root.exe] main (no debug info)
[/usr/lib/system/libdyld.dylib] start (no debug info)
Error in <HandleInterpreterException>: Trying to dereference null pointer or trying to call routine taking non-null arguments.
Execution of your code was aborted.
In file included from input_line_10:1:
~/test.cc:17:4: warning: null passed to a callee that requires a non-null argument [-Wnonnull]
   st1->SetName("MC");

h2->Draw("SAMES");

BTW. In the end, you need: pad1->Modified(); pad1->Update();

Ahh thank you for the hints, it seems after setting gStyle->SetOptStat(1); in the global environment the object can now be found.

Hi, a follow-up question on this, after creating a second pad and drawing the ratio:

   TH1F *r1 = (TH1F*)h2->Clone("r1");
   r1->Divide(h1);
   r1->Draw("eps");

The statbox of h2 appeared on the second pad. How can I delete this extra statbox? I tried pad2->Update(); TPaveStats *st = (TPaveStats*)r1->GetListOfFunctions()->FindObject("stats"); but it gets null again. Also tried r1->SetStats(0) but no effect.

Before “Draw”, try to add: r1->SetStats(kFALSE);

BTW. If you modify an object after “Draw”, you need: gPad->Modified(); gPad->Update();

It doesn’t work, the second pad still has the second TPaveStats’ info on it. Here is the full test code I’m using.

void test(){
   gStyle->SetOptStat(1);

   TCanvas * c =  new TCanvas("c", "c", 800, 800);
   TH1F* h1 = new TH1F("h1", "h1", 10, 0, 10);
   TH1F* h2 = new TH1F("h2", "h2", 10, 0, 10);

   h1->Fill(4);
   h2->Fill(4, 6);

   TPad *pad1 = new TPad("pad1", "pad1", 0, 0.3, 1, 1.0);
   pad1->Draw();
   pad1->cd();

   h1->Draw();
   pad1->Update();
   TPaveStats *st1 = (TPaveStats*)h1->GetListOfFunctions()->FindObject("stats");
   st1->SetName("MC");
   st1->SetX1NDC(0.8);
   st1->SetX2NDC(0.95);
   st1->SetY1NDC(0.5);
   st1->SetY2NDC(0.65);

   h2->Draw("sames");
   pad1->Update();
   TPaveStats *st2 = (TPaveStats*)h2->GetListOfFunctions()->FindObject("stats");
   st2->SetName("Data");

   st2->SetX1NDC(0.8);
   st2->SetX2NDC(0.95);
   st2->SetY1NDC(0.65);
   st2->SetY2NDC(0.8);

   pad1->Modified(); pad1->Update();

   c->cd();
   TPad *pad2 = new TPad("pad2", "pad2", 0, 0, 1, 0.3);
   pad2->Draw();
   pad2->cd();

   h1->SetStats(kFALSE);
   h2->SetStats(kFALSE);
   TH1F *r1 = (TH1F*)h1->Clone("r1");
   r1->Divide(h2);
   r1->SetStats(kFALSE);
   r1->Draw("ep");
   pad2->Modified(); pad2->Update();

}

r1->GetListOfFunctions()->Clear(); // remove the "MC" box
r1->SetStats(kFALSE); // prevent the "stats" box

This works nicely, thank you very much!

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