Changing TLegend (TPave) positioning after construction with SetX1(Y1)NDC?

If I draw the TLegend, then change the coordinates of the legend, then call Modified, the legend is drawn at the new coordinates. As demonstrated by your macro.

But if I change the coordinates first, then Draw, the legend is still drawn at the old coordinates.

This point was also raised in the thread I linked to, from five years ago: TPaveText position before drawing

Changing your macro from:

   TLegend *tl = new TLegend( 0.55, 0.65, 0.75, 0.85 );
...
   tl->Draw();
   gPad->Update();
   tl->SetX1NDC(0.01);
   tl->SetX2NDC(0.9);
   gPad->Modified(); // drawn at new coordinates

to

   TLegend *tl = new TLegend( 0.55, 0.65, 0.75, 0.85 );
...
   tl->SetX1NDC(0.01);
   tl->SetX2NDC(0.9);
   tl->Draw();
   tl->Update();
   gPad->Modified(); // drawn at old coordinates

(moving gPad->Modified() before tl->Draw() has no effect)

This is a bit annoying in my case, because I draw the legend inside some method that also draws other objects (DrawAll() draws a stack, a legend, a TGraph, etc…). If I call DrawAll(), I will have to retrieve the legend from the pad (GetPrimitive?), then SetX1NDC, then redraw it.

e.g.

void foo::DrawAll() {
  this->DrawStack();
  this->DrawSignal();
  this->DrawData();
  this->DrawLegend();
}
void foo::DrawLegend() {

TStyle *s = gROOT->GetStyle("ATLAS");
float leftMargin = s->GetPadLeftMargin();
float topMargin = s->GetPadTopMargin();
m_Legend.SetX1NDC(leftMargin+0.02);
m_Legend.SetX2NDC(leftMargin+0.02+0.3);
m_Legend.SetY1NDC(1-topMargin-0.02-0.15);
m_Legend.SetY2NDC(1-topMargin-0.02);
m_Legend.Draw();

}
TCanvas c("ctemp", "", cwx, cwy);
c.cd();
hc.DrawAll();
// DrawAll calls DrawLegend, which sets the coordinates of m_Legend before drawing it
// but m_Legend is not drawn with the new coordinates!
// non-ideal solution: I will have to go into the canvas, grab the TLegend, set its coordinates, and redraw it
c.Update();
c.Print(...);

UPDATE:
The solution I’ve implemented for now is: DrawLegend() does Draw, gPad->Update(), sets the coordinates, then gPad->Modified(). I think setting the coordinates before drawing should draw the legend at the new coordinates though…instead of this workaround of setting the coordinates after drawing, then Updating the pad…

1 Like