ROOT TText/TLatex size bug with precision 3 fonts

Dear ROOT experts,

I encounter a bug regarding the horizontal size of any TLatex or TText placed inside a pad with a height smaller than the canvas’ if the font is set to precision 3. Essentially, if the pad is constructed with

pad_top = root.TPad('pad_top', '', 0, 0.27, 1, 1)

instead of

pad_top = root.TPad('pad_top', '', 0, 0, 1, 1)

then label.GetXsize() returns the wrong value, where label is a TLatex. This also happens with TText, if using label.GetBoundingBox(width, height) to get the label’s width. If the font is set to a lower precision, the problem goes away.

The following script illustrates the problem:

import ctypes
import ROOT as root

root.gStyle.SetTextFont(43)
root.gStyle.SetTextSize(29)

#root.gStyle.SetTextFont(42)
#root.gStyle.SetTextSize(0.05)

canvas_hist = root.TCanvas('canvas', '', 0, 0, 800, 800)

#pad_top = root.TPad('pad_top', '', 0, 0, 1, 1)
pad_top = root.TPad('pad_top', '', 0, 0.27, 1, 1)
pad_top.Draw()
pad_top.cd()

hist = root.TH1D('test', '', 7, 0, 7)
hist.FillRandom("gaus", 10000)
hist.Draw()

pad_top.Update()

plotLabel = root.TLatex()
label = plotLabel.DrawLatexNDC(0.2, 0.77, 'MC mc16d, Data 2017')

w, h = ctypes.c_uint(), ctypes.c_uint()
label.GetBoundingBox(w, h)

x0 = root.gPad.PixeltoX(root.gPad.UtoPixel(label.GetX()))
x1 = root.gPad.PixeltoX(root.gPad.UtoPixel(label.GetX()) + w.value)

print('Label:', f'{x0=}', f'{x1=}')
print('Same values with label.GetXsize():')
print(f'{x1=}, {x0 + label.GetXsize()=}')

canvas_hist.Print('test.eps')

ROOT Version: 6.24/06, installed through Anaconda
Platform: Arch Linux / ROOT conda docker container
Compiler: GCC


Indeed GetXsize()and GetYsize() return a size in user coordinates which is valid when the text size is defined the usual way: in user coordinates. In that mode the text size stay constant relatively to the user coordinate. If you grow and shrink the pad you will see the text growing and shrinking accordingly. When you decide to have the text size in pixels (precision 3) then the text size does not change when you grow and shrink the pad. It stays constant in pixel. That mode is useful when you want some text looking the same in different user coordinates. And in that mode the value returned by GetXsize()and GetYsize() are not relevant. May be that should be documented.

Ohh, I didn’t know about that. Thanks for the quick reply! Yes, perhaps it would be good for that to be in the TText/TLatex documentation. Is there any way to get the correct text length when in precision 3? I’m trying to write a script that can autoscale the y axis of a plot to avoid any overlap with the legend and any labels written in the plot, so I need a way to get their size.

I’ll do the necessary updates in the documentation. Thanks to have pointed this deficiency. I will come back to you with a small example showing how to get what you are looking for.

1 Like

See this example:

void beaucamp(){
   gStyle->SetTextFont(43);
   gStyle->SetTextSize(50);

   auto canvas_hist = new TCanvas("canvas", "", 0, 0, 800, 800);

   auto pad_top = new TPad("pad_top", "", 0, 0., 1, 1);
   pad_top->Draw();
   pad_top->cd();

   auto hist = new TH1D("test", "", 100, 0, 7);
   hist->FillRandom("gaus", 100000);
   hist->Draw();

   double x = 1;
   double y = 3000;

   auto label = new TText(x, y, "MC mc16d, Data 2017");
   label->Draw();
   gPad->Update();

   Int_t cBoxX[4], cBoxY[4];
   label->GetControlBox(gPad->XtoAbsPixel(x), gPad->YtoAbsPixel(y), 0., cBoxX, cBoxY);

   auto l = new TLine(gPad->AbsPixeltoX(cBoxX[0]), y, gPad->AbsPixeltoX(cBoxX[2]), y);
   l->SetLineWidth(7.);
   l->SetLineColor(kRed);
   l->Draw();
}


I will update the doc tomorrow.

Thanks! I tried it and now works great with TText labels. However, if the label class is changed from TText to TLatex, the red line becomes shorter again. And if I make the TPad shorter in height, the line becomes even shorter in length. In this case, it doesn’t matter, since I can use a TText, but if any extra annotations that involve symbols need to be made on a plot, then it becomes a problem.


Yes there seems to be be an issue with TLatex and precision number 3.
I will look. I am not sure that can be easily fixed.
Also with TMathText the control box is not correct in case of precision 3.

This PR fixes the issue. Thanks t have seen it.

void beaucamp(){
    gStyle->SetTextFont(43);
    gStyle->SetTextSize(50);

   auto canvas_hist = new TCanvas("canvas", "", 0, 0, 800, 800);

   auto pad_top = new TPad("pad_top", "", 0, 0.27, 1, 1);
   pad_top->Draw();
   pad_top->cd();

   auto hist = new TH1D("test", "", 100, 0, 7);
   hist->FillRandom("gaus", 100000);
   hist->Draw();

   double x1 = 0.1;
   double x2 = 4.;
   double y = 3000;

   auto latex = new TLatex(x1, y, "#sqrt{TLatex text}");
   latex->Draw(); gPad->Update();
   Int_t cBoxX[4], cBoxY[4];
   latex->GetControlBox(gPad->XtoAbsPixel(x1), gPad->YtoAbsPixel(y), 0., cBoxX, cBoxY);
   auto l1 = new TLine(gPad->AbsPixeltoX(cBoxX[0]), y, gPad->AbsPixeltoX(cBoxX[2]), y);
   l1->SetLineWidth(3.);
   l1->SetLineColor(kRed);
   l1->Draw();

   auto text = new TText(x2, y, "TText text");
   text->Draw(); gPad->Update();
   Int_t cBoxX2[4], cBoxY2[4];
   text->GetControlBox(gPad->XtoAbsPixel(x2), gPad->YtoAbsPixel(y), 0., cBoxX2, cBoxY2);
   auto l2 = new TLine(gPad->AbsPixeltoX(cBoxX2[0]), y, gPad->AbsPixeltoX(cBoxX2[2]), y);
   l2->SetLineWidth(3.);
   l2->SetLineColor(kRed);
   l2->Draw();
}

I fixed also TMathText.
The PR is now merged in master.

Awesome, thanks!

1 Like

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