Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 35 additions & 29 deletions graf2d/gpad/src/TPad.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -1254,6 +1254,9 @@ Int_t TPad::DistancetoPrimitive(Int_t px, Int_t py)
/// __Note3:__ in case xmargin < 0 or ymargin < 0, there is no space
/// between pads. The current pad margins are recomputed to
/// optimize the layout.
///
/// __Note4:__ in case nx < 0 or ny < 0, there is no outer x or y margin, but
/// the inner margins are equal to xmargin and ymargin, respectively.

void TPad::Divide(Int_t nx, Int_t ny, Float_t xmargin, Float_t ymargin, Int_t color)
{
Expand All @@ -1269,40 +1272,43 @@ void TPad::Divide(Int_t nx, Int_t ny, Float_t xmargin, Float_t ymargin, Int_t co
TContext ctxt(kTRUE);

cd();
if (nx <= 0) nx = 1;
if (ny <= 0) ny = 1;
Int_t ix, iy;
Double_t x1, y1, x2, y2, dx, dy;
TPad *pad;
if (nx == 0)
nx = 1;
if (ny == 0)
ny = 1;

Double_t xl = GetLeftMargin();
Double_t xr = GetRightMargin();
Double_t yb = GetBottomMargin();
Double_t yt = GetTopMargin();

TString name, title;
Int_t n = 0;
if (color == 0) color = GetFillColor();
if (xmargin >= 0 && ymargin >= 0) {
//general case
dy = 1/Double_t(ny);
dx = 1/Double_t(nx);
for (iy=0;iy<ny;iy++) {
y2 = 1 - iy*dy - ymargin;
y1 = y2 - dy + 2*ymargin;
if (y1 < 0) y1 = 0;
if (y1 > y2) continue;
for (ix=0;ix<nx;ix++) {
x1 = ix*dx + xmargin;
x2 = x1 +dx -2*xmargin;
if (x1 > x2) continue;
auto dx = (1 - xl - xr - xmargin * (nx - 1)) / nx; // width of a subpad
auto dy = (1 - yt - yb - ymargin * (ny - 1)) / ny; // height of a subpad

Int_t n = 0;
for (auto iy = 0; iy < ny; iy++) {
auto y2 = 1 - yt - iy * (dy + ymargin);
auto y1 = y2 - dy;
if (y1 < yb)
y1 = yb;
for (auto ix = 0; ix < nx; ix++) {
auto x1 = xl + ix * (dx + xmargin);
auto x2 = x1 + dx;
if (x2 > (1 - xr))
xr = 1 - xr;
n++;
name.Form("%s_%d", GetName(), n);
pad = new TPad(name.Data(), name.Data(), x1, y1, x2, y2, color);
auto pad = new TPad(name.Data(), name.Data(), x1, y1, x2, y2, color);
pad->SetNumber(n);
pad->Draw();
}
}
} else {
// special case when xmargin < 0 or ymargin < 0
Double_t xl = GetLeftMargin();
Double_t xr = GetRightMargin();
Double_t yb = GetBottomMargin();
Double_t yt = GetTopMargin();
xl /= (1-xl+xr)*nx;
xr /= (1-xl+xr)*nx;
yb /= (1-yb+yt)*ny;
Expand All @@ -1311,23 +1317,23 @@ void TPad::Divide(Int_t nx, Int_t ny, Float_t xmargin, Float_t ymargin, Int_t co
SetRightMargin(xr);
SetBottomMargin(yb);
SetTopMargin(yt);
dx = (1-xl-xr)/nx;
dy = (1-yb-yt)/ny;
auto dx = (1 - xl - xr) / nx;
auto dy = (1 - yb - yt) / ny;
Int_t number = 0;
for (Int_t i=0;i<nx;i++) {
x1 = i*dx+xl;
x2 = x1 + dx;
auto x1 = i * dx + xl;
auto x2 = x1 + dx;
if (i == 0) x1 = 0;
if (i == nx-1) x2 = 1-xr;
for (Int_t j=0;j<ny;j++) {
number = j*nx + i +1;
y2 = 1 -j*dy -yt;
y1 = y2 - dy;
auto y2 = 1 - j * dy - yt;
auto y1 = y2 - dy;
if (j == 0) y2 = 1-yt;
if (j == ny-1) y1 = 0;
name.Form("%s_%d", GetName(), number);
title.Form("%s_%d", GetTitle(), number);
pad = new TPad(name.Data(), title.Data(), x1, y1, x2, y2, color);
auto pad = new TPad(name.Data(), title.Data(), x1, y1, x2, y2, color);
pad->SetNumber(number);
pad->SetBorderMode(0);
if (i == 0) pad->SetLeftMargin(xl*nx);
Expand Down
131 changes: 131 additions & 0 deletions tutorials/visualisation/graphics/canvas_divide_example.C
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
// variants: 0 - custom values
// 1 - default values
// 2+ - old default values
void canvas_divide_example(int use_variant = 0)
{
auto wx = 600; // width and heigh
auto wy = 400;

auto nx = 3; // top-level pad division
auto ny = 2;

auto ml = 0.30; // top-level pad margins
auto mb = 0.10;
auto mr = 0.05;
auto mt = 0.10;

auto c = new TCanvas("canvas_divide", "canvas_divide", wx, wy);
c->SetFillColor(19);

if (use_variant == 0) {
c->SetLeftMargin(ml);
c->SetBottomMargin(mb);
c->SetRightMargin(mr);
c->SetTopMargin(mt);

c->Divide(nx, ny, 0.03, 0.05, 46);
} else if (use_variant == 1) {
c->Divide(nx, ny, 0.01, 0.01, 46);
} else {
c->SetLeftMargin(0.01);
c->SetBottomMargin(0.01);
c->SetRightMargin(0.01);
c->SetTopMargin(0.01);

c->Divide(nx, ny, 0.02, 0.02, 46);
}

ml = c->GetLeftMargin();
mb = c->GetBottomMargin();
mr = c->GetRightMargin();
mt = c->GetTopMargin();

auto h = new TH1F("", "", 100, -3.3, 3.3);
h->GetXaxis()->SetLabelFont(43);
h->GetXaxis()->SetLabelSize(12);
h->GetYaxis()->SetLabelFont(43);
h->GetYaxis()->SetLabelSize(12);
h->GetYaxis()->SetNdivisions(505);
h->SetMaximum(30 * nx * ny);
h->SetFillColor(41);

Int_t number = 0;
for (Int_t i = 0; i < nx * ny; i++) {
number++;
c->cd(number);
h->FillRandom("gaus", 1000);
h->DrawCopy();
}

c->cd();

TArrow arr;

arr.DrawArrow(0, 0.5, ml, 0.5, 0.01, "<|>");
arr.DrawArrow(0.5, 0, 0.5, mb, 0.01, "<|>");
arr.DrawArrow(1 - mr, 0.5, 1, 0.5, 0.01, "<|>");
arr.DrawArrow(0.5, 1 - mt, 0.5, 1, 0.01, "<|>");

TLatex tex_x;
tex_x.SetNDC(1);
tex_x.SetTextSize(0.03);
tex_x.SetTextAlign(12);
tex_x.SetTextAngle(90);

TLatex tex_y;
tex_y.SetNDC(1);
tex_y.SetTextSize(0.03);
tex_y.SetTextAlign(12);

tex_x.DrawLatex(ml / 2, 0.5, TString::Format(" ml = %.2f", ml));
tex_x.DrawLatex(1 - mr / 2, 0.5, TString::Format(" mr = %.2f", mr));

tex_y.DrawLatex(0.5, mb / 2, TString::Format(" mb = %.2f", mb));
tex_y.DrawLatex(0.5, 1 - mt / 2, TString::Format(" mt = %.2f", mt));

for (int i = 0; i < nx; ++i) {
for (int j = 0; j < ny; ++j) {

float x1, x2, xc, y1, y2, yc;

auto spad = c->GetPad(1 + j * nx + i); // current pad
x1 = spad->GetXlowNDC() + spad->GetWNDC();
xc = spad->GetXlowNDC() + spad->GetWNDC() / 2;
if (i < (nx - 1)) {
auto spad_nx = c->GetPad(1 + j * nx + (i + 1)); // next pad in x
x2 = spad_nx->GetXlowNDC();
}
auto xm = x2 - x1;

if (j < (ny - 1)) {
auto spad_ny = c->GetPad(1 + (j + 1) * nx + i); // next pad in y
y1 = spad_ny->GetYlowNDC() + spad->GetHNDC();
}
y2 = spad->GetYlowNDC();
yc = spad->GetYlowNDC() + spad->GetHNDC() / 2;
auto ym = y2 - y1;

if (i < (nx - 1)) {
arr.DrawArrow(x1, yc, x2, yc, 0.01, "<|>");
tex_x.DrawLatex((x1 + x2) / 2, yc, TString::Format(" xm = %.2f", xm));
}
if (j < (ny - 1)) {
arr.DrawArrow(xc, y1, xc, y2, 0.01, "<|>");
tex_y.DrawLatex(xc, (y1 + y2) / 2, TString::Format(" ym = %.2f", ym));
}
}
}

TText text;
text.SetTextSize(0.03);
text.SetTextFont(102);
text.SetNDC(1);

if (use_variant == 0) {
text.DrawText(0.01, 0.90, "c->SetLeftMargin(ml);");
text.DrawText(0.01, 0.85, "c->SetBottomMargin(mb);");
text.DrawText(0.01, 0.80, "c->SetRightMargin(mr);");
text.DrawText(0.01, 0.75, "c->SetTopMargin(mt);");
text.DrawText(0.01, 0.70, "c->Divide(nx, ny, xm, ym);");
}
}