Adding TLatex text to different pads of same canvas

Hi all, I am trying to add text to my plot. I have a canvas which is divided into 4, and I am trying to add text to each one of these 4 pads with TLatex. I tried accessing one pad at a time and adding the text, and then move on to the next pad and so on. However, the problem is that all of my text is added on top of each other on the same pad (the 4th pad). Does anyone know what I am doing wrong? Thanks!

#include "TFile.h"
#include "TCanvas.h"
#include "TH1.h"
#include "TMultiGraph.h"
#include "TVectorD.h"
#include "TGraphAsymmErrors.h"
#include "TString.h"
#include <vector>
#include <iostream>
#include "TLatex.h"

void mjj(const char *fname = "HaddOutput.root") {
  if (!(fname && fname[0])) return; // just a precaution
  TFile *f = TFile::Open(fname);
  if ((!f) || f->IsZombie()) { delete f; return; } // just a precaution

  std::vector<int> pT1Cut = {85, 130, 145, 220};
  std::vector<int> pT2Cut = {60, 70, 85, 90, 100, 110, 120, 130, 145, 150, 160, 170, 185, 190, 200, 210, 220};
  int n1 = pT1Cut.size();
  int n2 = pT2Cut.size();
    
  TCanvas *c = new TCanvas("c", "", (n1 * 350), 1000);
  c->Divide(2, 2)
  c->SetFillColor(0);
    
  std::vector<std::vector<double> > offset {
      {160,170,190},
      {250, 250, 250, 255, 260, 285, 295, 320},
      {285, 285, 285, 287, 290, 295, 307, 320, 350},
      {450,450,450,450,450,450,450,450,450,450, 450, 460, 480, 480, 490, 500, 520},
    };
  
    TH1D *h[n1];
    TH1D *k[n1][n2];
    TF1 *fit[n1][n2];
    TF1 *sigmoid[n1][n2];
    TMultiGraph *mg[n1];
    TGraphAsymmErrors *eff[n1][n2];
    TH1D *histo = (TH1D*)f->Get("AfterCuts/yCut_0.6/pT1Cut_0/pT2Cut_0/Mjj");  
  
    std::vector<std::vector<double> > x_value(4, std::vector<double> (17));
    
    for (int i = 0; i < n1; i++) {
    c->cd(i + 1);
    f->GetObject(TString::Format("AfterCuts/yCut_0.6/pT1Cut_%d/pT2Cut_0/Mjj", pT1Cut[i]), h[i]);
    if (!h[i]) continue; // just a precaution
    mg[i] = new TMultiGraph();
    
    for (int j = 0; j < n2; j++) {
      f->GetObject(TString::Format("AfterCuts/yCut_0.6/pT1Cut_%d/pT2Cut_%d/Mjj", pT1Cut[i], pT2Cut[j]), k[i][j]);
      if (!k[i][j]) continue; // just a precaution
      if (pT2Cut[j] > pT1Cut[i]) continue; // skip unwanted
      eff[i][j] = new TGraphAsymmErrors();
      eff[i][j]->Divide(k[i][j], histo, "n");
                 
      for (int m = (eff[i][j]->GetN() - 1); m>=0; m--) {
	    if (eff[i][j]->GetY()[m] < 0.997) eff[i][j]->RemovePoint(m);
      }
       
       mg[i]->Add(eff[i][j], "p");                
       fit[i][j] = new TF1("sigm_%d",  "(1/(1+ TMath::Exp(-[0]*(x-[1]))))", 0, 1500); // Sigmoid fit to efficiency plots
       fit[i][j]->SetParameters(0.28, offset[i][j]);
       fit[i][j]->SetLineColor(kGray);
       eff[i][j]->Fit("sigm_%d", "EX0");
     
       sigmoid[i][j] = eff[i][j]->GetFunction(fit[i][j]->GetName()); // Find turn-on
       x_value[i][j] = sigmoid[i][j]->GetX(0.999, x_min[i][j], x_max[i][j]);
    }
    
      mg[i]->GetYaxis()->SetTitle("Efficiency");
      mg[i]->GetXaxis()->SetTitle("M_{jj} (GeV)");    
      mg[i]->GetXaxis()->SetLimits(0, 1500);       
      
      mg[i]->Draw("AL");
      } 
  
     c->cd(0);

     c->cd(1);
     TLatex text1(20,0.9996,"#splitline{|y*| < 0.6}{p_{T}^{lead} > 85 GeV}");
     text1.SetTextSize(0.04);
     text1.DrawClone();
     
     c->cd(2);
     TLatex text2(40,0.9996,"#splitline{|y*| < 0.6}{p_{T}^{lead} > 130 GeV}");
     text2.SetTextSize(0.04);
     text2.DrawClone();
     
     c->cd(3);
     TLatex text3(40,0.9996,"#splitline{|y*| < 0.6}{p_{T}^{lead} > 145 GeV}");
     text3.SetTextSize(0.04);
     text3.DrawClone();
  }

@couet can you please take a look?

Thank you in advance,
Oksana.

void evdv1() {
   auto c = new TCanvas();
   c->Divide(2,2);

   c->cd(1); gPad->DrawFrame(0.,0.,40.,2.);
   c->cd(2); gPad->DrawFrame(0.,0.,60.,2.);
   c->cd(3); gPad->DrawFrame(0.,0.,60.,2.);

   c->cd(1);
   auto text1 = new TLatex(20,0.9996,"#splitline{|y*| < 0.6}{p_{T}^{lead} > 85 GeV}");
   text1->SetTextSize(0.04);
   text1->Draw();

   c->cd(2);
   auto text2 = new TLatex(40,0.9996,"#splitline{|y*| < 0.6}{p_{T}^{lead} > 130 GeV}");
   text2->SetTextSize(0.04);
   text2->Draw();

   c->cd(3);
   auto text3 = new TLatex(40,0.9996,"#splitline{|y*| < 0.6}{p_{T}^{lead} > 145 GeV}");
   text3->SetTextSize(0.04);
   text3->Draw();
}

@couet So the problem is related to “DrawClone” (just replace “Draw” with “DrawClone” in your test macro).

@evdv A temporary solution could be to always use: c->cd(...); gPad->Update();

But why using DrawClone ? … Draw is recommended simple way… you even even create one single TLatex and use DrawLatex

Stack-based versus heap-based objects.

Also, when using python, it may be more convenient due to python’s garbage collection (i.e. to “hide” one’s drawn objects from it).

The TObject::DrawClone functionality was initially made to be used interactively to
Draw an Object in the interactively selected pad (see the code). The right way will be the following (But that’s quite heavy. Using Draw() is much better seems to me)…

void evdv1() {
   auto c = new TCanvas();
   c->Divide(2,2);

   c->cd(1); gPad->DrawFrame(0.,0.,40.,2.);
   c->cd(2); gPad->DrawFrame(0.,0.,60.,2.);
   c->cd(3); gPad->DrawFrame(0.,0.,60.,2.);

   gROOT->SetSelectedPad(c->cd(1));
   auto text1 = new TLatex(20,0.9996,"#splitline{|y*| < 0.6}{p_{T}^{lead} > 85 GeV}");
   text1->SetTextSize(0.04);
   text1->DrawClone();

   gROOT->SetSelectedPad(c->cd(2));
   auto text2 = new TLatex(40,0.9996,"#splitline{|y*| < 0.6}{p_{T}^{lead} > 130 GeV}");
   text2->SetTextSize(0.04);
   text2->DrawClone();

   gROOT->SetSelectedPad(c->cd(3));
   auto text3 = new TLatex(40,0.9996,"#splitline{|y*| < 0.6}{p_{T}^{lead} > 145 GeV}");
   text3->SetTextSize(0.04);
   text3->DrawClone();
}

Thank you both!

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