{ "cells": [ { "cell_type": "markdown", "id": "2127a7e5", "metadata": {}, "source": [ "# canvas2\n", "Sometimes the Divide() method is not appropriate to divide a Canvas.\n", "Because of the left and right margins, all the pads do not have the\n", "same width and height. CanvasPartition does that properly. This\n", "example also ensure that the axis labels and titles have the same\n", "sizes and that the tick marks length is uniform.\n", "In addition, XtoPad and YtoPad allow to place graphics objects like\n", "text in the right place in each sub-pads.\n", "\n", "\n", "\n", "\n", "**Author:** Olivier Couet \n", "This notebook tutorial was automatically generated with ROOTBOOK-izer from the macro found in the ROOT repository on Tuesday, May 19, 2026 at 08:36 PM." ] }, { "cell_type": "code", "execution_count": 1, "id": "e8c5593a", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:36:51.458551Z", "iopub.status.busy": "2026-05-19T20:36:51.458421Z", "iopub.status.idle": "2026-05-19T20:36:51.797976Z", "shell.execute_reply": "2026-05-19T20:36:51.795685Z" } }, "outputs": [], "source": [ "void CanvasPartition(TCanvas *C, const Int_t Nx = 2, const Int_t Ny = 2, Float_t lMargin = 0.15, Float_t rMargin = 0.05,\n", " Float_t bMargin = 0.15, Float_t tMargin = 0.05);\n", "double XtoPad(double x);\n", "double YtoPad(double x);" ] }, { "cell_type": "markdown", "id": "0ceadc5c", "metadata": {}, "source": [ " Definition of a helper function: " ] }, { "cell_type": "code", "execution_count": 2, "id": "22ae2238", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:36:51.800157Z", "iopub.status.busy": "2026-05-19T20:36:51.800031Z", "iopub.status.idle": "2026-05-19T20:36:51.813160Z", "shell.execute_reply": "2026-05-19T20:36:51.812689Z" } }, "outputs": [], "source": [ "%%cpp -d\n", "void CanvasPartition(TCanvas *C, const Int_t Nx, const Int_t Ny, Float_t lMargin, Float_t rMargin, Float_t bMargin,\n", " Float_t tMargin)\n", "{\n", " if (!C)\n", " return;\n", "\n", " // Setup Pad layout:\n", " Float_t vSpacing = 0.0;\n", " Float_t vStep = (1. - bMargin - tMargin - (Ny - 1) * vSpacing) / Ny;\n", "\n", " Float_t hSpacing = 0.0;\n", " Float_t hStep = (1. - lMargin - rMargin - (Nx - 1) * hSpacing) / Nx;\n", "\n", " Float_t vposd, vposu, vmard, vmaru, vfactor;\n", " Float_t hposl, hposr, hmarl, hmarr, hfactor;\n", "\n", " for (Int_t i = 0; i < Nx; i++) {\n", "\n", " if (i == 0) {\n", " hposl = 0.0;\n", " hposr = lMargin + hStep;\n", " hfactor = hposr - hposl;\n", " hmarl = lMargin / hfactor;\n", " hmarr = 0.0;\n", " } else if (i == Nx - 1) {\n", " hposl = hposr + hSpacing;\n", " hposr = hposl + hStep + rMargin;\n", " hfactor = hposr - hposl;\n", " hmarl = 0.0;\n", " hmarr = rMargin / (hposr - hposl);\n", " } else {\n", " hposl = hposr + hSpacing;\n", " hposr = hposl + hStep;\n", " hfactor = hposr - hposl;\n", " hmarl = 0.0;\n", " hmarr = 0.0;\n", " }\n", "\n", " for (Int_t j = 0; j < Ny; j++) {\n", "\n", " if (j == 0) {\n", " vposd = 0.0;\n", " vposu = bMargin + vStep;\n", " vfactor = vposu - vposd;\n", " vmard = bMargin / vfactor;\n", " vmaru = 0.0;\n", " } else if (j == Ny - 1) {\n", " vposd = vposu + vSpacing;\n", " vposu = vposd + vStep + tMargin;\n", " vfactor = vposu - vposd;\n", " vmard = 0.0;\n", " vmaru = tMargin / (vposu - vposd);\n", " } else {\n", " vposd = vposu + vSpacing;\n", " vposu = vposd + vStep;\n", " vfactor = vposu - vposd;\n", " vmard = 0.0;\n", " vmaru = 0.0;\n", " }\n", "\n", " C->cd(0);\n", "\n", " auto name = TString::Format(\"pad_%d_%d\", i, j);\n", " auto pad = (TPad *)C->FindObject(name.Data());\n", " if (pad)\n", " delete pad;\n", " pad = new TPad(name.Data(), \"\", hposl, vposd, hposr, vposu);\n", " pad->SetLeftMargin(hmarl);\n", " pad->SetRightMargin(hmarr);\n", " pad->SetBottomMargin(vmard);\n", " pad->SetTopMargin(vmaru);\n", "\n", " pad->SetFrameBorderMode(0);\n", " pad->SetBorderMode(0);\n", " pad->SetBorderSize(0);\n", "\n", " pad->Draw();\n", " }\n", " }\n", "}" ] }, { "cell_type": "markdown", "id": "d16f9491", "metadata": {}, "source": [ " Definition of a helper function: " ] }, { "cell_type": "code", "execution_count": 3, "id": "bda73f95", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:36:51.816521Z", "iopub.status.busy": "2026-05-19T20:36:51.816399Z", "iopub.status.idle": "2026-05-19T20:36:51.819683Z", "shell.execute_reply": "2026-05-19T20:36:51.819212Z" } }, "outputs": [], "source": [ "%%cpp -d\n", "double XtoPad(double x)\n", "{\n", " double xl, yl, xu, yu;\n", " gPad->GetPadPar(xl, yl, xu, yu);\n", " double pw = xu - xl;\n", " double lm = gPad->GetLeftMargin();\n", " double rm = gPad->GetRightMargin();\n", " double fw = pw - pw * lm - pw * rm;\n", " return (x * fw + pw * lm) / pw;\n", "}" ] }, { "cell_type": "markdown", "id": "c083bea8", "metadata": {}, "source": [ " Definition of a helper function: " ] }, { "cell_type": "code", "execution_count": 4, "id": "d0d01b0f", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:36:51.821011Z", "iopub.status.busy": "2026-05-19T20:36:51.820891Z", "iopub.status.idle": "2026-05-19T20:36:51.823709Z", "shell.execute_reply": "2026-05-19T20:36:51.823235Z" } }, "outputs": [], "source": [ "%%cpp -d\n", "double YtoPad(double y)\n", "{\n", " double xl, yl, xu, yu;\n", " gPad->GetPadPar(xl, yl, xu, yu);\n", " double ph = yu - yl;\n", " double tm = gPad->GetTopMargin();\n", " double bm = gPad->GetBottomMargin();\n", " double fh = ph - ph * bm - ph * tm;\n", " return (y * fh + bm * ph) / ph;\n", "}" ] }, { "cell_type": "code", "execution_count": 5, "id": "f1577676", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:36:51.824966Z", "iopub.status.busy": "2026-05-19T20:36:51.824855Z", "iopub.status.idle": "2026-05-19T20:36:52.034580Z", "shell.execute_reply": "2026-05-19T20:36:52.034017Z" } }, "outputs": [], "source": [ "gStyle->SetOptStat(0);\n", "\n", "auto C = (TCanvas *)gROOT->FindObject(\"C\");\n", "if (C)\n", " delete C;\n", "C = new TCanvas(\"C\", \"canvas\", 1024, 640);\n", "C->SetFillStyle(4000);" ] }, { "cell_type": "markdown", "id": "720eea6e", "metadata": {}, "source": [ "Number of PADS" ] }, { "cell_type": "code", "execution_count": 6, "id": "e29edc14", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:36:52.036279Z", "iopub.status.busy": "2026-05-19T20:36:52.036159Z", "iopub.status.idle": "2026-05-19T20:36:52.246025Z", "shell.execute_reply": "2026-05-19T20:36:52.245053Z" } }, "outputs": [], "source": [ "const Int_t Nx = 5;\n", "const Int_t Ny = 5;" ] }, { "cell_type": "markdown", "id": "a5511186", "metadata": {}, "source": [ "Margins" ] }, { "cell_type": "code", "execution_count": 7, "id": "d17276c4", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:36:52.247416Z", "iopub.status.busy": "2026-05-19T20:36:52.247300Z", "iopub.status.idle": "2026-05-19T20:36:52.457024Z", "shell.execute_reply": "2026-05-19T20:36:52.455999Z" } }, "outputs": [], "source": [ "Float_t lMargin = 0.12;\n", "Float_t rMargin = 0.05;\n", "Float_t bMargin = 0.15;\n", "Float_t tMargin = 0.05;" ] }, { "cell_type": "markdown", "id": "f054f1e9", "metadata": {}, "source": [ "Canvas setup" ] }, { "cell_type": "code", "execution_count": 8, "id": "0f751908", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:36:52.458440Z", "iopub.status.busy": "2026-05-19T20:36:52.458325Z", "iopub.status.idle": "2026-05-19T20:36:52.668408Z", "shell.execute_reply": "2026-05-19T20:36:52.667421Z" } }, "outputs": [], "source": [ "CanvasPartition(C, Nx, Ny, lMargin, rMargin, bMargin, tMargin);" ] }, { "cell_type": "markdown", "id": "20bc2f8f", "metadata": {}, "source": [ "Dummy histogram." ] }, { "cell_type": "code", "execution_count": 9, "id": "5918db00", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:36:52.669823Z", "iopub.status.busy": "2026-05-19T20:36:52.669699Z", "iopub.status.idle": "2026-05-19T20:36:53.008047Z", "shell.execute_reply": "2026-05-19T20:36:53.007471Z" } }, "outputs": [], "source": [ "auto h = (TH1F *)gROOT->FindObject(\"histo\");\n", "if (h)\n", " delete h;\n", "h = new TH1F(\"histo\", \"\", 100, -5.0, 5.0);\n", "h->FillRandom(\"gaus\", 10000);\n", "h->GetXaxis()->SetTitle(\"x axis\");\n", "h->GetYaxis()->SetTitle(\"y axis\");\n", "\n", "TPad *pad[Nx][Ny];\n", "\n", "for (Int_t i = 0; i < Nx; i++) {\n", " for (Int_t j = 0; j < Ny; j++) {\n", " C->cd(0);\n", "\n", " // Get the pads previously created.\n", " pad[i][j] = (TPad *)C->FindObject(TString::Format(\"pad_%d_%d\", i, j).Data());\n", " pad[i][j]->Draw();\n", " pad[i][j]->SetFillStyle(4000);\n", " pad[i][j]->SetFrameFillStyle(4000);\n", " pad[i][j]->cd();\n", "\n", " // Size factors\n", " Float_t xFactor = pad[0][0]->GetAbsWNDC() / pad[i][j]->GetAbsWNDC();\n", " Float_t yFactor = pad[0][0]->GetAbsHNDC() / pad[i][j]->GetAbsHNDC();\n", "\n", " TH1F *hFrame = (TH1F *)h->Clone(TString::Format(\"h_%d_%d\", i, j).Data());\n", "\n", " // y axis range\n", " hFrame->SetMinimum(0.0001); // do not show 0\n", " hFrame->SetMaximum(1.2 * h->GetMaximum());\n", "\n", " // Format for y axis\n", " hFrame->GetYaxis()->SetLabelFont(43);\n", " hFrame->GetYaxis()->SetLabelSize(16);\n", " hFrame->GetYaxis()->SetLabelOffset(0.02);\n", " hFrame->GetYaxis()->SetTitleFont(43);\n", " hFrame->GetYaxis()->SetTitleSize(16);\n", " hFrame->GetYaxis()->SetTitleOffset(2);\n", "\n", " hFrame->GetYaxis()->CenterTitle();\n", " hFrame->GetYaxis()->SetNdivisions(505);\n", "\n", " // TICKS Y Axis\n", " hFrame->GetYaxis()->SetTickLength(xFactor * 0.04 / yFactor);\n", "\n", " // Format for x axis\n", " hFrame->GetXaxis()->SetLabelFont(43);\n", " hFrame->GetXaxis()->SetLabelSize(16);\n", " hFrame->GetXaxis()->SetLabelOffset(0.02);\n", " hFrame->GetXaxis()->SetTitleFont(43);\n", " hFrame->GetXaxis()->SetTitleSize(16);\n", " hFrame->GetXaxis()->SetTitleOffset(1);\n", " hFrame->GetXaxis()->CenterTitle();\n", " hFrame->GetXaxis()->SetNdivisions(505);\n", "\n", " // TICKS X Axis\n", " hFrame->GetXaxis()->SetTickLength(yFactor * 0.06 / xFactor);\n", "\n", " // Draw cloned histogram with individual settings\n", " hFrame->Draw();\n", "\n", " TText text;\n", " text.SetTextAlign(31);\n", " text.SetTextFont(43);\n", " text.SetTextSize(10);\n", " text.DrawTextNDC(XtoPad(0.9), YtoPad(0.8), gPad->GetName());\n", " }\n", "}\n", "C->cd();" ] }, { "cell_type": "markdown", "id": "71ee0f83", "metadata": {}, "source": [ "Draw all canvases " ] }, { "cell_type": "code", "execution_count": 10, "id": "6775de8c", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:36:53.012248Z", "iopub.status.busy": "2026-05-19T20:36:53.012129Z", "iopub.status.idle": "2026-05-19T20:36:53.221539Z", "shell.execute_reply": "2026-05-19T20:36:53.220972Z" } }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "