Drawing divided canvas in loop

Hi,

Ultimately I am trying to loop over numerous variables of two types (signal or background) with various cuts applied (ranging from -1 to 0 for background types and 0 to 1 for signal types). For each variable and type I want to plot on the same divided canvas each histogram with it’s set of cuts.

The problem is that the individual histograms are getting drawn but the divided canvas is coming out blank.

Including relevant bits of code:

     std::vector<std::string> Variables = { "AbsDeltaPhi", "DeltaY", "Lambda", "qTSquared", "CosThetaCS", "PhiCS", "DiMuonMass","DiMuonTau"};
   
      std::vector<std::string> EventType = {"Signal", "Background"};

     std::vector<std::string>  BDTcutsSignal = { "0.0", "0.3", "0.6"};
     std::vector<std::string> BDTcutsBackground =  { "0.0", "-0.3", "-0.6"};

   TCanvas *c;
   c = new TCanvas ("c", "c",  1800, 500);
   c->Divide(2,1);

   int  k=0;

   TString canvaslabel;

   TH1F *h[BDTcutsSignal.size()];

 for(int var=0; var<variables.size() ; var++){
    for (int type = 0; type< EventType.size(); type++){

    canvaslabel = TString(Form("%s_%s",Variables[var].c_str(), EventType[type].c_str() ));
    c = new TCanvas (canvaslabel, canvaslabel, 800, 800);

      for (int cut=0; cut< BDTcutsSignal.size(); cut++){

     k++;
   
h[cut] =(TH1F*)file->Get(Form("%s_%s_%s",Variables[var].c_str(), EventType[type].c_str(), BDTcutsSignal[cut].c_str()) );
if (h[cut]==0){
    std::cout << Variables[var] << "_" << EventType[type] << "_" << BDTcutsSignal[cut] <<  "  Not Found" << std::endl; 
}
       c->cd(k);
       h[cut]->Draw();
      }
     }
    }

ROOT Version: Not Provided
Platform: Not Provided
Compiler: Not Provided


When you do

c->cd(k);

c is not the divided canvas as you have redefined it in the loop as a non divided canvas

Hi,

I moved the divide line to inside the loop where I draw, but still getting the same issue.

Hi,
I notice you put k=0 only outside the loops and so k becomes larger and larger and you have only 1 canvas divided in 2 sub pads, maybe this can cause the issue.

Cheers,
Stefano

Hi,

I’m fairly certain I have it divided into 3 subpads, but I have just three histograms.

Divide(2,1) produces 2 sub-pads. So k can only have two values: 1 and 2.
Can you verify it is the case (with a print for instance) ?

Whit this line you divide the canvas in 2 rows x 1 column.
By the way you redefine a new canvas at each loop, so you only see the last three histograms

Ahh sorry, I have redefined it to be 2x2 now.

I changed it to Divide(2,2), and k has the values of 1,2 and 3.

Can you post the macro you have now ?

  std::vector<std::string> Variables = { "AbsDeltaPhi", "DeltaY", "Lambda", "qTSquared", "CosThetaCS", "PhiCS", "DiMuonMass","DiMuonTau"};

  std::vector<std::string> EventType = {"Signal", "Background"};

  std::vector<std::string>  BDTcutsSignal = { "0.0", "0.3", "0.6"};
 std::vector<std::string> BDTcutsBackground =  { "0.0", "-0.3", "-0.6"};

 TCanvas *c;

 int k=0;

TString canvaslabel;

TH1F *h[BDTcutsSignal.size()];

 for(int var=0; var<Variables.size(); var++){
   for (int type = 0; type< EventType.size(); type++){
 
  canvaslabel = TString(Form("%s_%s",Variables[var].c_str(), EventType[type].c_str() ));
  c = new TCanvas (canvaslabel, canvaslabel, 800, 800);
  
  for (int cut=0; cut< BDTcutsSignal.size(); cut++){

k++;
c->Divide(2,2);


   	std::cout << "k: " << k << std::endl;
std::cout << "cut: " << cut << std::endl;

     //Declare an empty histogram
h[cut] =(TH1F*)file->Get(Form("%s_%s_%s",Variables[var].c_str(), EventType[type].c_str(), BDTcutsSignal[cut].c_str()) );
if (h[cut]==0){
    std::cout << Variables[var] << "_" << EventType[type] << "_" << BDTcutsSignal[cut] <<  "  Not Found" << std::endl; 
}


  c->cd(k);
  h[cut]->Draw();
  }


  }
}
  c = new TCanvas(canvaslabel, canvaslabel, 800, 800);
  c->Divide(2, 2);
  int k = 1;
  // ...
    c->cd(k++);

Hi,

Sadly the canvas is still coming out blank :frowning:

It is drawing the individual histograms for each iteration of the loop, and then drawing a blank canvas which is mean to be the TCanvas c.
Amy

Can you provide a macro we can run ?

Hi,
try to change line

with line

c->cd(cut+1); 
h[cut]->Draw();

and k shouldn’t be needed.

Cheers,
Steano

From the code it seems that you want (Variables_size)x(EventType_size) = 8 x 2 = 16 canvases, with each canvas (divided in 2x2) showing 3 histos (for each cut, either signal or background). If you create the same canvas ( c ) inside the loops, as you are doing, you lose the “previous” canvas at each iteration.
I would create an array of canvases, say c[Variables.Size()][EventType.Size()].
You also need another loop and more histograms for the background; e.g. you can have hs[BDTcutsSignal.size()] and hb[BDTcutsBackground.size()].
Something like:

  std::vector<std::string> Variables = {"AbsDeltaPhi", "DeltaY", "Lambda", "qTSquared", "CosThetaCS", "PhiCS", "DiMuonMass","DiMuonTau"};
  std::vector<std::string> EventType = {"Signal", "Background"};
  std::vector<std::string> BDTcutsSignal = {"0.0", "0.3", "0.6"};
  std::vector<std::string> BDTcutsBackground = {"0.0", "-0.3", "-0.6"};

  TCanvas *c[Variables.Size()][EventType.Size()];
  TString canvaslabel;
  TH1F *hs[BDTcutsSignal.size()];
  TH1F *hb[BDTcutsBackground.size()];

  for (int var=0; var<Variables.size(); var++) {
    for (int type=0; type<EventType.size(); type++) {
      canvaslabel = TString(Form("%s_%s",Variables[var].c_str(), EventType[type].c_str()));
      c[var][type] = new TCanvas(canvaslabel, canvaslabel, 800, 800);
      c[var][type]->Divide(2,2);
      if (type==0) {
        for (int cut=0; cut<BDTcutsSignal.size(); cut++){
          std::cout << "cut: " << cut << std::endl;
          //Declare an empty histogram
          hs[cut] = (TH1F*)file->Get(Form("%s_%s_%s",Variables[var].c_str(), EventType[type].c_str(), BDTcutsSignal[cut].c_str()) );
          if (hs[cut]==0){
            std::cout << Variables[var] << "_" << EventType[type] << "_" << BDTcutsSignal[cut] <<  "  Not Found" << std::endl; 
          }
          c[var][type]->cd(cut+1);
          hs[cut]->Draw();
        }
      }
      else {
        for (int cut=0; cut<BDTcutsBackground.size(); cut++){
          std::cout << "cut: " << cut << std::endl;
          //Declare an empty histogram
          hb[cut] = (TH1F*)file->Get(Form("%s_%s_%s",Variables[var].c_str(), EventType[type].c_str(), BDTcutsBackground[cut].c_str()) );
          if (hb[cut]==0){
            std::cout << Variables[var] << "_" << EventType[type] << "_" << BDTcutsBackground[cut] <<  "  Not Found" << std::endl; 
          }
          c[var][type]->cd(cut+1);
          hb[cut]->Draw();
        }
      }
    }
  }


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