Home | News | Documentation | Download

Multiple TPads in a Canvas - ResizePad Issue


#1

ROOT Version: 6.12.04
Platform: Fedora 27
Compiler: gcc version 7.3.1 20180303 (Red Hat 7.3.1-5) (GCC)


Dear co-rooters,

I am trying to plot multiple TPolarGraphs on the same TCanvas. The image I would like to reproduce is the following

I thought of creating a dummy TH1F histogram in order to have the proper axes and then a TCanvas on which I will create TPads.

The code I wrote to accomplish that is the following

void nuclei_shapes(){

TF1 *Leg2 = new TF1("Leg2", "(3.*pow( TMath::Cos(x), 2 ) - 1. )/2.", 0, 2.*TMath::Pi());
TF1 *Leg4 = new TF1("Leg4", "(35.*pow(TMath::Cos(x) , 4) - 30.*pow( TMath::Cos(x), 2 ) + 3. )/8.", 0, 2.*TMath::Pi()); 

TF1         f[7][13];
TGraphPolar g[7][13];			

double x[1000];
double y[1000];
double  a2[7] = {0, .4, .8, 1.2, 1.6, 2., 2.4};
double a4[13] = {-.6, -.4, -.2, 0., .2, .4, .6, .8, 1., 1.2, 1.4, 1.6, 1.8}; 

for (int i=0; i<7; ++i){
	for (int j=0; j<13; ++j){
		char fname[20];
		sprintf(fname, "f_%d_%d", i+1, j+1);
		f[i][j] = TF1(fname, "1. + [0]*Leg2(x) - [1]*Leg4(x)", 0, 2.*TMath::Pi());
		f[i][j].SetParameter(0, a2[i]);
		f[i][j].SetParameter(1, a4[j]);
		//f[i][j].Draw("same");
		sprintf(fname, "g_%d_%d", i+1, j+1);
		for (int l=0; l<1000; ++l){
			x[l] = l*TMath::Pi()/500.;
			y[l] = f[i][j].Eval(x[l]);
		}
		g[i][j] = TGraphPolar(1000, x, y);		
		//g[i][j].SetLineColor(i+j);
		//g[i][j].Draw("same");
	}
}
TH1F *hdummy = new TH1F("hdummy", "", 2, -0.2, 2.5);
hdummy->SetBinContent(1, -0.7);
hdummy->SetBinContent(2, 1.9);
hdummy->SetLineWidth(0);

double size_Canvas = 1080.;
double size_Pad    = 80.;
TCanvas *c= new TCanvas("c", "c", size_Canvas, size_Canvas);
hdummy->Draw();

TPad *p[7][13];
TLatex L;
L.SetTextSize(0.2);

double x_low, x_up, y_low, y_up;
for (int i=0; i<7; ++i){
	for (int j=0; j<13; ++j){
		char fname[20];
		sprintf(fname, "p_%d_%d", i, j);
			x_low = (260.+i*size_Pad)/size_Canvas;
			x_up  = (260.+(i+1.)*size_Pad)/size_Canvas;
			y_low = (20.+j*size_Pad)/size_Canvas;
			y_up  = (20.+(j+1.)*size_Pad)/size_Canvas;			
			p[i][j] = new TPad(fname, fname, x_low, y_low, x_up, y_up, -1, 5, 0);
			p[i][j]->SetFillStyle(4000); 
			p[i][j]->Draw();
			p[i][j]->Draw();
			p[i][j]->cd();
			//L.DrawLatex(0.5, 0.5, TString::Format("%d - %d", i, j));			
			//cout << x_low << ", " << x_up << ", " << y_low << ", " << y_up << endl;
			g[i][j].Draw("AFL");
			c->Update();
			g[i][j].GetPolargram()->SetNdivPolar(1);
			g[i][j].GetPolargram()->SetNdivRadial(0);
			g[i][j].GetPolargram()->SetPolarLabelSize(0);
			g[i][j].GetPolargram()->SetRadialLabelSize(0);
			g[i][j].GetPolargram()->SetLineColor(kWhite);
			g[i][j].SetLineColor(kBlack);
			g[i][j].SetLineWidth(2);
	}
}


}

The problem is that when I run the code I get the following warnings and errors

Error in : invalid pad’s geometry

Warning in TPad::ResizePad: p_4_0 width changed from 0 to 10

The error is there only when I draw the TGraphPolars. But the warnings are there in any case.

I tried to find a solution by printing a TLatex on each pad to see if they are properly created, however it seems that there is an issue which I cannot find : Only for the first TPad p[0][0] I get the TLatex drawn.

Any idea on what might be the issue and how to reproduce the image?

Thanks in advance!


#3
			c->cd(0);
			p[i][j]->Draw();
			p[i][j]->cd();
			//L.DrawLatex(0.5, 0.5, TString::Format("%d - %d", i, j));			
			//cout << x_low << ", " << x_up << ", " << y_low << ", " << y_up << endl;
			g[i][j].Draw("AFL");
			gPad->Modified(); gPad->Update();

#4

Before creating (drawing … see Wile post below) a new pad you should cd() to the canvas otherwise you willl create the new pad in the previous on created.

void nuclei_shapes(){

   TF1 *Leg2 = new TF1("Leg2", "(3.*pow( TMath::Cos(x), 2 ) - 1. )/2.", 0, 2.*TMath::Pi());
   TF1 *Leg4 = new TF1("Leg4", "(35.*pow(TMath::Cos(x) , 4) - 30.*pow( TMath::Cos(x), 2 ) + 3. )/8.", 0, 2.*TMath::Pi());

   TF1         f[7][13];
   TGraphPolar g[7][13];

   double x[1000];
   double y[1000];
   double  a2[7] = {0, .4, .8, 1.2, 1.6, 2., 2.4};
   double a4[13] = {-.6, -.4, -.2, 0., .2, .4, .6, .8, 1., 1.2, 1.4, 1.6, 1.8};

   for (int i=0; i<7; ++i){
      for (int j=0; j<13; ++j){
         char fname[20];
         sprintf(fname, "f_%d_%d", i+1, j+1);
         f[i][j] = TF1(fname, "1. + [0]*Leg2(x) - [1]*Leg4(x)", 0, 2.*TMath::Pi());
         f[i][j].SetParameter(0, a2[i]);
         f[i][j].SetParameter(1, a4[j]);
         //f[i][j].Draw("same");
         sprintf(fname, "g_%d_%d", i+1, j+1);
         for (int l=0; l<1000; ++l){
            x[l] = l*TMath::Pi()/500.;
            y[l] = f[i][j].Eval(x[l]);
         }
         g[i][j] = TGraphPolar(1000, x, y);
         //g[i][j].SetLineColor(i+j);
         //g[i][j].Draw("same");
      }
   }


   double size_Canvas = 1080.;
   double size_Pad    = 80.;
   TCanvas *c= new TCanvas("c", "c", size_Canvas, size_Canvas);

   TPad *p[7][13];
   auto L = new TLatex();
   L->SetTextSize(0.2);

   double x_low, x_up, y_low, y_up;
   for (int i=0; i<7; ++i){
      for (int j=0; j<13; ++j){
         char fname[20];
         sprintf(fname, "p_%d_%d", i, j);
            c->cd();
            x_low = (260.+i*size_Pad)/size_Canvas;
            x_up  = (260.+(i+1.)*size_Pad)/size_Canvas;
            y_low = (20.+j*size_Pad)/size_Canvas;
            y_up  = (20.+(j+1.)*size_Pad)/size_Canvas;
            p[i][j] = new TPad(fname, fname, x_low, y_low, x_up, y_up);
            p[i][j]->Draw();
            p[i][j]->cd();
            L->DrawLatex(0.5, 0.5, TString::Format("%d - %d", i, j));
            g[i][j].Draw("AFL");
            c->Update();
            g[i][j].GetPolargram()->SetNdivPolar(1);
            g[i][j].GetPolargram()->SetNdivRadial(0);
            g[i][j].GetPolargram()->SetPolarLabelSize(0);
            g[i][j].GetPolargram()->SetRadialLabelSize(0);
            g[i][j].GetPolargram()->SetLineColor(kWhite);
            g[i][j].SetLineColor(kBlack);
            g[i][j].SetLineWidth(2);
      }
   }
}

#5

Actually, it’s not “before creating a new pad” but “before Draw()'ing a new pad”.


#6

You are both right!
Thank you very much for your help!