TPie - avoid circle stretching

Hi!

I’m playing a bit with TPie(s).
I noticed that if I the canvas width and height differ, the pie is not a circle but an ellipsis.
Is there a way to maintain the circle as a circle even when they differ?

Just to give an example:

void pc()
{
	Float_t vals[] = {.2,1.1,.6,.9,2.3};
	Int_t colors[] = {2,3,4,5,6};
	Int_t nvals = sizeof(vals)/sizeof(vals[0]);

	TCanvas *cpie = new TCanvas("cpie","TPie test",700,400);
	TPie *pie4 = new TPie("pie4","Pie with verbose labels",nvals,vals,colors);
	pie4->SetCircle(0.40, 0.5, 0.30);
	pie4->Draw("nol");
	TLegend *legend = pie4->MakeLegend();
	legend->SetX1(0.82);
	legend->SetX2(0.98);
	legend->SetY1(0.75);
	legend->SetY2(0.9);
}

This macro produces a pie which is actually an ellipsis.

If you wonder why I am asking this: I want to save the output picture and not having to edit that using some picture editor software in order to trim the unneeded white area.

Thank you!

One solution would be to keep a fixed canvas size:

TCanvas *c1 = new TCanvas("c1","c1");
c1->SetCanvasSize(1500, 1500);

Then, when resizing the Windows, you will get scrollbars. Another solution would be to react to every window resize and recompute the drawing, but this is more complex…

Uhm…
I’d like to save the output picture without having to edit/resize/whatever.
That means that the root macro that I’m currently writing will end with a c->SaveAs(“whatever.gif”).

Well, then c1->SetCanvasSize(1500, 1500); is the right solution

Indeed, the point is: how to let the user change the canvas shape without affecting the shape of the pie itself! :slight_smile:
I don’t want square canvas because then I had to trim the extra&unneeded&unwanted white areas.

Then create a square TPad inside the rectangle Canvas

May I ask you some help with this?
I’ve never used TPads. I don’t know how to tell root to draw the Pie on that, and not on the canvas.

Maybe there is a simpler solution. Could you try with TCanvas::SetFixedAspectRatio()?

Here we go:

void pc()
{
	Float_t vals[] = {.2,1.1,.6,.9,2.3};
	Int_t colors[] = {2,3,4,5,6};
	Int_t nvals = sizeof(vals)/sizeof(vals[0]);

	TCanvas *cpie = new TCanvas("cpie","TPie test",700,400);
	cpie->SetFixedAspectRatio(kTRUE);
	TPad *pad = new TPad("pad", "pad", 0.2142857, 0., 0.7857142857, 1.0);
	pad->Draw();
	pad->cd();
	TPie *pie4 = new TPie("pie4","Pie with verbose labels",nvals,vals,colors);
	pie4->SetCircle(0.40, 0.5, 0.30);
	pie4->Draw("nol");
	TLegend *legend = pie4->MakeLegend();
	legend->SetX1(0.82);
	legend->SetX2(0.98);
	legend->SetY1(0.75);
	legend->SetY2(0.9);
}
1 Like
{
  Float_t vals[] = {.2,1.1,.6,.9,2.3};
  Int_t colors[] = {2,3,4,5,6};
  Int_t nvals = sizeof(vals)/sizeof(vals[0]);
  
  TCanvas *cpie = new TCanvas("cpie","TPie test",700,400);
  // cpie->SetFixedAspectRatio(kTRUE); // only if needed
  // create a square sub-pad
  Double_t ratio = (double)cpie->GetWw() / (double)cpie->GetWh();
  TPad *square;
  if (ratio > 1.) square = new TPad("square", "square", 0., 0., 1. / ratio, 1.);
  else square = new TPad("square", "square", 0., 0., 1., ratio);
  square->Draw();
  square->cd(); // switch to the square sub-pad
  // draw the pie in the square sub-pad
  TPie *pie4 = new TPie("pie4","Pie with verbose labels",nvals,vals,colors);
  pie4->SetCircle(0.40, 0.5, 0.30);
  pie4->Draw("nol");
  cpie->cd(0); // return to the main pad
  // draw the legend in the main pad
  TLegend *legend = pie4->MakeLegend();
  legend->SetX1(0.82);
  legend->SetX2(0.98);
  legend->SetY1(0.75);
  legend->SetY2(0.9);
}
1 Like

So it’s just about “cd” to the pad I want to use.

Thank you both for your help. :slight_smile:

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