KAHIBARO
Discord Login Register

8.2. Dividing a Canvas

Table of Contents

Multiple plots

A canvas is the ROOT window where you draw your plots. To compare several plots side by side, you usually divide a single TCanvas into subregions and draw one object in each of them. This keeps your layout organized and makes it easier to visually compare shapes, scales, and features.

The standard way to divide a canvas is with the Divide() method of TCanvas. After creating a canvas, you tell ROOT how many subpads you want in the horizontal and vertical directions. For example, in an interactive ROOT session:

cpp
auto c1 = new TCanvas("c1", "My canvas", 800, 600);
c1->Divide(2, 2);  // 2 columns, 2 rows, 4 pads in total

This creates a 2 by 2 grid. Each cell is a separate drawing area. To draw something into a particular subpad, you first select it with the cd() method, then call Draw() on your object:

cpp
c1->cd(1);
h1->Draw();
c1->cd(2);
h2->Draw();
c1->cd(3);
h3->Draw();
c1->cd(4);
h4->Draw();

Pad numbering starts at 1 and increases row by row. For a grid with nx columns and ny rows, the total number of pads is nx * ny, and you can access them from 1 to that number.

Important rule:
Always call canvas->cd(pad_number); before Draw() if you want to control where an object appears. If you forget this, ROOT will draw on whichever pad is currently active, which may not be the one you expect.

You can also use different layouts by changing the arguments to Divide. A Divide(1, 2) arrangement gives one column and two rows, which is useful if you want one plot above another, for example a main plot and a residual plot. A Divide(3, 1) layout gives three plots side by side. The idea is always the same. Create the canvas, divide it, select the desired pad, and draw in it.

Divide() has optional arguments that let you control the spacing between pads and margins, but for most beginner use cases the simple two-argument version Divide(nx, ny) is enough. Once you have divided a canvas, changing the active pad with cd() becomes part of your normal plotting workflow whenever you want multiple plots in a single window.

To update the entire canvas after drawing into several pads, you can call:

cpp
c1->Update();

This is especially useful in macros or scripts when you want to make sure all pads are fully rendered, for example before saving the canvas to a file.

Pads

When you divide a canvas, ROOT internally creates several TPad objects. A pad is a rectangular subarea of a canvas that can contain its own axes, histograms, graphs, and even further subdivisions. Conceptually, a TCanvas is a special kind of pad that lives at the top level, and each cell that appears after Divide() is a TPad inside that canvas.

Each pad behaves like a mini canvas. It has its own coordinate system, margins, and drawing options. When you call c1->cd(2);, ROOT sets the second subpad as the current pad, and any subsequent Draw() calls will affect that pad. You can access the current pad through the global pointer gPad, which always refers to the pad that is currently active:

cpp
c1->cd(1);
gPad->SetGrid();  // Turn on grid for pad 1
h1->Draw();
c1->cd(2);
gPad->SetLogy();  // Logarithmic Y axis only in pad 2
h2->Draw();

This allows different visual settings in different regions of the same canvas, for example a linear scale in one pad and a logarithmic scale in another. Each pad stores and controls the style of the objects drawn inside it.

You can also create pads manually without using Divide(). In that case you construct a TPad with coordinates relative to the canvas, then draw and use it:

cpp
auto c2 = new TCanvas("c2", "Custom pads", 800, 600);
// Create a pad that occupies the top half of the canvas
auto padTop = new TPad("padTop", "Top pad", 0.0, 0.5, 1.0, 1.0);
padTop->Draw();
// Create a pad that occupies the bottom half
auto padBottom = new TPad("padBottom", "Bottom pad", 0.0, 0.0, 1.0, 0.5);
padBottom->Draw();
// Draw in the top pad
padTop->cd();
hTop->Draw();
// Draw in the bottom pad
padBottom->cd();
hBottom->Draw();

The four numeric arguments of TPad are the lower left and upper right corners in normalized coordinates from 0 to 1, where (0, 0) is the bottom left of the canvas and (1, 1) is the top right. Manual pads are useful when you need a nonuniform layout, such as a tall pad for a main plot and a shorter pad for residuals.

Important rule:
Remember that pads are hierarchical. You can create pads inside other pads. Always use pad->cd(); to select the correct level before drawing, or you may accidentally draw into the wrong pad.

Because each pad has its own margins and style, you can tune the layout very precisely. For example, you can reduce the top margin of interior pads so that axes and labels do not overlap, or set different axis ranges in each pad for focused comparisons. You still save the entire set of pads by saving the parent canvas, for example:

cpp
c1->SaveAs("multipanel.pdf");

All pads inside the canvas are stored in the single image. This is the standard ROOT approach for creating multipanel figures that contain several related plots in a single view.

Views: 12

Comments

Please login to add a comment.

Don't have an account? Register now!