Pad coordinates with THStack

Dear Root experts,

I encountered that when drawing a THStack and accessing the axis information, changes all results regarding pad coordinates, going from normal pad coordinates (0 to 1), to axis coordinates.

In this example I calculate the width of a TLatex label in different parts of the code:

  1. Before creating a canvas
  2. After creating a canvas
  3. After drawing the stack
  4. After modifying the axis of the stack
------------------------------- before everything
SM total                                    0.0
#gamma + jets Pythia                        0.0
jet#rightarrow#gamma fake                   0.0
------------------------------- after creating canvas
SM total                                    0.12781954887218044
#gamma + jets Pythia                        0.21553884711779447
jet#rightarrow#gamma fake                   0.15914786967418545
------------------------------- after drawing stack
SM total                                    0.12781954887218044
#gamma + jets Pythia                        0.21553884711779447
jet#rightarrow#gamma fake                   0.15914786967418545
------------------------------- after modified axis
SM total                                    15.977443847105032
#gamma + jets Pythia                        26.942356291196724
jet#rightarrow#gamma fake                   19.893484005709208

As you can see, in the last step the width now is given in user coordinates in the X axis.

Is this a bug, or how can I circumvent this issue?

Best regards,

Francisco

test2.py (2.9 KB)


ROOT Version: 6.28
Platform: Any


May be try to set the text size in pixel. ie Precision 3.

The reason I came across with this problem is because I have a plotting framework that will automatically calculate sizes of legends and labels so they are automatically accommodated in the room they have. Changing the text precision would indeed save me from doing this calculation, and directly placing everything by using the size in pixels. However I don’t want to move to precision 3 in my framework since it would break other things. BTW, I found a way to have the legend and labels placed before accessing the TAxis attributes of the stack in my framework without changing precision.

However, I want to know if this behavior is expected or not.

I tried changing the text precision and it’s still changing sizes:

------------------------------- before everything
SM total                                    0.0
#gamma + jets Pythia                        0.0
jet#rightarrow#gamma fake                   0.0
------------------------------- after creating canvas
SM total                                    0.05513784461152882
#gamma + jets Pythia                        0.09147869674185463
jet#rightarrow#gamma fake                   0.06641604010025062
------------------------------- after drawing stack
SM total                                    0.05513784461152882
#gamma + jets Pythia                        0.09147869674185463
jet#rightarrow#gamma fake                   0.06641604010025062
------------------------------- after modified axis
SM total                                    6.892230679143347
#gamma + jets Pythia                        11.43483726312419
jet#rightarrow#gamma fake                   8.302005136240851

On the other hand, I tried this for a simple TH1 for two cases:

  1. Having ROOT.gPad.Modified(); ROOT.gPad.Update() in the code after accessing the TAxis attributes.
    In this case the result is the SAME as for the THStack case (changing sizes to user coordinates)
  2. Not adding ROOT.gPad.Modified(); ROOT.gPad.Update().
    Here the result is the EXPECTED one (having the size in pad coordinates)

Cheers,
Francisco

I do not know. I need to study your example (the fact it is in python makes it less easy)

Can you try:

# Draw the stacked histograms
stack.Draw()
ROOT.gPad.Modified()
ROOT.gPad.Update()

This changes the result in a previous step:

------------------------------- before everything
SM total                                    0.0
#gamma + jets Pythia                        0.0
jet#rightarrow#gamma fake                   0.0
------------------------------- after creating canvas
SM total                                    0.12781954887218044
#gamma + jets Pythia                        0.21553884711779447
jet#rightarrow#gamma fake                   0.15914786967418545
------------------------------- after drawing stack
SM total                                    15.977443847105032
#gamma + jets Pythia                        26.942356291196724
jet#rightarrow#gamma fake                   19.893484005709208
------------------------------- after modified axis
SM total                                    15.977443847105032
#gamma + jets Pythia                        26.942356291196724
jet#rightarrow#gamma fake                   19.893484005709208

I wrote the code in C++. I leave the macro here:
test2.C (4.0 KB)

I think your question can be summarised with:

void textxsize() {
  auto t = new TLatex(.5,.5,"Hello");
  printf("No canvas               %g\n",t->GetXsize());
  auto C = new TCanvas();
  printf("Empty canvas            %g\n",t->GetXsize());
  C->DrawFrame(0.,0., 1.,1.);
  t->Draw();
  printf("Canvas with coordinates %g\n",t->GetXsize());
}

As the text size use the canvas coordinate to be computed this behavior is fine.

Uhmm I see.

Looking at the documentation of the TLatex TLatex::GetXsize function, it clearly states that the size is calculated in pad coordinates, but this behavior changes if there are axes plotted as you and I have shown. Can this be said in the documentation?, since this is misleading.

Also, is there a way to consistently get the size? This method gets sizes in user and pad coordinates, but it’s not possible to convert USER coordinates to NDC coordinates as shown here. Would it be possible to have a way to either get the size of a label in a fixed coordinate system or to convert USER → NDC coordinates values?

Cheers,
Francisco

You you draw plot which define/draw the axis it defines the user coordinates also. “Drawing a plot” , “Drawing Axis”, “defining user coordinates” re kind of synonyms.

Make sure the plot is drawn or use pixel size.

void textxsize() {
  auto t = new TLatex(.5,.5,"Hello");
  printf("No canvas               Xsize = %5.2g\n",t->GetXsize());
  auto C = new TCanvas();
  printf("Empty canvas            Xsize = %5.2g X1 = %g X2 = %g\n",t->GetXsize(),C->GetX1(), C->GetX2());
  C->DrawFrame(0.,0., 1.,1.);
  t->Draw();
  printf("Canvas with coordinates Xsize = %5.2g X1 = %g X2 = %g\n",t->GetXsize(),C->GetX1(), C->GetX2());
}

gives:

No canvas               Xsize =     0
Empty canvas            Xsize = 0.076 X1 = 0 X2 = 1
Canvas with coordinates Xsize = 0.095 X1 = -0.125 X2 = 1.125

Size is directly computed from X1 and X2…

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