Adding new entry to the stats box doesn't work

I have the example code to attach, adding new entry to the statistics box doesn’t work. Also the first statistics box line color doesn’t change as expected if I have multiple stats box.

#include "TCanvas.h"
#include "TH1.h"
#include "TStyle.h"
#include "TPaveStats.h"
#include "TLatex.h"

void addCustomStat() {
    TCanvas *se = new TCanvas;
    se->SetFillStyle(0);
    se->SetFrameFillStyle(0);
    se->Print("addCustomStat.pdf[");
    TH1F *h1 = new TH1F("Gaus","Gaus",100,-3,3); 
    TH1F *h2 = new TH1F("Poly","Poly",100,-3,3); 
    h1->FillRandom("gaus",3000); 
    h2->FillRandom("landau",3000); 
    h1->Scale(1.0/h1->Integral());
    h2->Scale(1.0/h2->Integral());
    gStyle->SetOptStat(); // Enable the statistics box
    h1->Draw("hist");
    if(h1->GetMaximum()<h2->GetMaximum()) h1->GetYaxis()->SetRangeUser(0.0, h2->GetMaximum()*1.1);
    gPad->Update(); 
    TPaveStats *ps = (TPaveStats*)h1->FindObject("stats"); 
    ps->SetFillStyle(0);
    ps->SetX1NDC(1.0-gPad->GetRightMargin()-0.2); ps->SetX2NDC(1.0-gPad->GetRightMargin());
    ps->SetY1NDC(1.0-gPad->GetTopMargin()-0.2); ps->SetY2NDC(1.0-gPad->GetTopMargin());
    ps->SetBorderSize(0);
    ps->SetTextColor(kBlue);
    ps->SetLineColor(kBlue);
    TList *listOfLines = ps->GetListOfLines();

    TLatex *myt = new TLatex(0,0,"New Entry = 123.45"); 
    myt->SetTextFont(42);
    myt->SetTextSize(0.04);
    myt->SetTextColor(kRed);
    listOfLines->Add(myt);
    listOfLines->ls();
    se->Modified(); 
    se->Update(); // Update the canvas again to display the changes

    h2->Draw("hist sames");
    h2->SetLineColor(kRed);
    gPad->Update(); 
    ps = (TPaveStats*)h2->FindObject("stats"); 
    ps->SetFillStyle(0);
    ps->SetX1NDC(1.0-gPad->GetRightMargin()-0.2); ps->SetX2NDC(1.0-gPad->GetRightMargin());
    ps->SetY1NDC(1.0-gPad->GetTopMargin()-0.4); ps->SetY2NDC(1.0-gPad->GetTopMargin()-0.2);
    ps->SetBorderSize(0);
    ps->SetTextColor(kRed);
    ps->SetLineColor(kRed);

    // Prevent the statistics box from being redrawn automatically
    //h->SetStats(0); 
    se->Modified(); 
    se->Update(); // Update the canvas again to display the changes
    se->Print("addCustomStat.pdf");
    se->Print("addCustomStat.pdf]");
}

addCustomStat.pdf (14.8 KB)

addCustomStat.cpp (1.9 KB)

ROOT Version: 6.36.02
Platform: macOS
Compiler: Not Provided


After you obtain the “ps” pointer, either:
ps->SetName("stats_1"); ps->Draw(); h1->SetStats(0); // ps remains in h1 list of associated functions
or:
ps = (TPaveStats*)ps->Clone("stats_1"); ps->Draw(); h1->SetStats(0); // ps disconnected from h1

ohhh, I see. I tried but missed the Draw() one.

ps->Draw();

Can you also check the separate line color in the first stats box? It should be blue but it shows as black. It related to

ps->SetFillStyle(0)

which set it as transparent, but weirdly the second stats works! You can see the separate line is red in the second stats.

@couet There is something wrong when the stats fill style is 0 (“ps->SetLineColor(...);” has no effect). I also get the horizontal line in the first stats box in black. The horizontal line in the second stats box is in red because it follows the line color of its “h2” histogram (try, e.g., “h2->SetLineColor(kGreen);”).

I’ll check

To remove the extra line do:

void addCustomStat() {
    TCanvas *se = new TCanvas;
    TH1F *h1 = new TH1F("Gaus","Gaus",100,-3,3);
    h1->FillRandom("gaus",3000);

    gStyle->SetOptStat();
    h1->Draw();
    gPad->Update();
    TPaveStats *ps = (TPaveStats*)h1->FindObject("stats");
    ps->SetName("stats_1"); ps->Draw(); h1->SetStats(0); // ps remains in h1 list of associated functions

    ps->SetX1NDC(1.0-gPad->GetRightMargin()-0.2); ps->SetX2NDC(1.0-gPad->GetRightMargin());
    ps->SetY1NDC(1.0-gPad->GetTopMargin()-0.2); ps->SetY2NDC(1.0-gPad->GetTopMargin());
    ps->SetBorderSize(1);
    ps->SetLineWidth(0);
    ps->SetTextColor(kBlue);
    ps->SetLineColor(kBlue);
}

The border size change the size of the border but not o the line inside.

I want to keep the inner line and remove the border and control the inner line color at the same time.

void addCustomStat() {
    TCanvas *se = new TCanvas;
    TH1F *h1 = new TH1F("Gaus","Gaus",100,-3,3);
    h1->FillRandom("gaus",3000);

    gStyle->SetOptStat();
    h1->Draw();
    gPad->Update();
    TPaveStats *ps = (TPaveStats*)h1->FindObject("stats");
    ps->SetName("stats_1");
    ps->Draw();
    h1->SetStats(0);

    ps->SetX1NDC(1.0-gPad->GetRightMargin()-0.2); ps->SetX2NDC(1.0-gPad->GetRightMargin());
    ps->SetY1NDC(1.0-gPad->GetTopMargin()-0.2); ps->SetY2NDC(1.0-gPad->GetTopMargin());
    // change the stats graphical attributes
    ps->SetBorderSize(0);
    ps->SetLineWidth(3);
    ps->SetLineColor(kRed);
    ps->SetTextColor(kBlue);
}

I tried this before, it worked if just one stats in the figure, while it doesn’t work anymore for the first stats though it works for the second stats (or maybe it just works for the last stats if you have multiple, I haven’t tested yet) if you add another stats which can be tested in my previous sample code

#include "TCanvas.h"
#include "TH1.h"
#include "TStyle.h"
#include "TPaveStats.h"
#include "TLatex.h"

void addCustomStat() {
    TCanvas *se = new TCanvas;
    se->SetFillStyle(0);
    se->SetFrameFillStyle(0);
    se->Print("addCustomStat.pdf[");
    TH1F *h1 = new TH1F("Gaus","Gaus",100,-3,3); 
    TH1F *h2 = new TH1F("Poly","Poly",100,-3,3); 
    h1->FillRandom("gaus",3000); 
    h2->FillRandom("landau",3000); 
    h1->Scale(1.0/h1->Integral());
    h2->Scale(1.0/h2->Integral());
    gStyle->SetOptStat(); // Enable the statistics box
    h1->Draw("hist");
    if(h1->GetMaximum()<h2->GetMaximum()) h1->GetYaxis()->SetRangeUser(0.0, h2->GetMaximum()*1.1);
    gPad->Update(); 
    TPaveStats *ps = (TPaveStats*)h1->FindObject("stats"); 
    ps->SetName(Form("stats_1"));
    ps->SetFillStyle(0);
    ps->SetX1NDC(1.0-gPad->GetRightMargin()-0.2); ps->SetX2NDC(1.0-gPad->GetRightMargin());
    ps->SetY1NDC(1.0-gPad->GetTopMargin()-0.2); ps->SetY2NDC(1.0-gPad->GetTopMargin());
    ps->SetBorderSize(0);
    ps->SetLineWidth(2);
    ps->SetTextColor(kBlue);
    ps->SetLineColor(kBlue);
    TList *listOfLines = ps->GetListOfLines();

    TLatex *myt = new TLatex(0,0,"New Entry = 123.45"); 
    myt->SetTextFont(42);
    myt->SetTextSize(0.03);
    myt->SetTextColor(kRed);
    listOfLines->Add(myt);
    ps->Draw();
    h1->SetStats(0);
    listOfLines->ls();
    se->Modified(); 
    se->Update(); // Update the canvas again to display the changes

    h2->Draw("hist sames");
    h2->SetLineColor(kRed);
    gPad->Update(); 
    ps = (TPaveStats*)h2->FindObject("stats"); 
    ps->SetFillStyle(0);
    ps->SetX1NDC(1.0-gPad->GetRightMargin()-0.2); ps->SetX2NDC(1.0-gPad->GetRightMargin());
    ps->SetY1NDC(1.0-gPad->GetTopMargin()-0.4); ps->SetY2NDC(1.0-gPad->GetTopMargin()-0.2);
    ps->SetBorderSize(0);
    ps->SetTextColor(kRed);
    ps->SetLineColor(kRed);

    // Prevent the statistics box from being redrawn automatically
    //h->SetStats(0); 
    se->Modified(); 
    se->Update(); // Update the canvas again to display the changes
    se->Print("addCustomStat.pdf");
    se->Print("addCustomStat.pdf]");
}

@mhstar Due to the bug you discovered, you either need to refrain from setting the stats fill style 0, or you need to “hide” the horizontal line (i.e., set its width 0).

This works for me.

void addCustomStat() {
auto se = new TCanvas;
auto h1 = new TH1F("Gaus","Gaus",100,-3,3);
auto h2 = new TH1F("Poly","Poly",100,-3,3);
h1->FillRandom("gaus",3000);
h2->FillRandom("landau",3000);

gStyle->SetOptStat();

h1->Draw();
gPad->Update();
TPaveStats *ps1 = (TPaveStats*)h1->FindObject("stats");
ps1->SetName("stats_1");
ps1->Draw();
h1->SetStats(0);
ps1->SetBorderSize(0);
ps1->SetLineWidth(3);
ps1->SetLineColor(kBlue);
ps1->SetTextColor(kBlue);

h2->Draw("hist sames");
gPad->Update();

TPaveStats *ps2 = (TPaveStats*)h2->FindObject("stats");
ps2->SetName("stats_2");
ps2->Draw();
h2->SetStats(0);
ps2->SetX1NDC(1.0-gPad->GetRightMargin()-0.2); ps2->SetX2NDC(1.0-gPad->GetRightMargin());
ps2->SetY1NDC(1.0-gPad->GetTopMargin()-0.4);   ps2->SetY2NDC(1.0-gPad->GetTopMargin()-0.2);
ps2->SetBorderSize(0);
ps2->SetLineWidth(3);
ps2->SetTextColor(kRed);
ps2->SetLineColor(kRed);

}

I know this cause you remove the fillstyle(0) while I want to keep the fill transparent. I guess as @Wile_E_Coyote said, it’s a bug.

Ah ok I see it now. But no need to draw two histograms. It is enough to do:

void addCustomStat() {
   auto se = new TCanvas;
   auto h1 = new TH1F("Gaus","Gaus",100,-3,3);
   h1->FillRandom("gaus",3000);
   gStyle->SetOptStat();
   h1->Draw();
   gPad->Update();
   TPaveStats *ps1 = (TPaveStats*)h1->FindObject("stats");
   ps1->SetName("stats_1");
   ps1->Draw();
   h1->SetStats(0);
   ps1->SetFillStyle(0);// if you comment this line it works
   ps1->SetBorderSize(0); 
   ps1->SetLineWidth(3); 
   ps1->SetLineColor(kBlue); 
   ps1->SetTextColor(kBlue);
}

@couet No, you don’t get my point. I want the stats fillstyle(0) without border but keep the separate line and control the separate line color. If you have more than one stats, the first stats’ separate line’ color is not changeable. This is part of my original question if you read carefully. As @Wile_E_Coyote pointed out, I think it’s a bug.

Yes it is a bug, I understand your point. In my previous example the line attribute cannot be changed if the Fill Style is 0. It works fine if the fill style is not 0. I am debugging that now.

I made a PR to fix this problem. Thanks to have seen it.