6.1. Creating 2D Histograms
Table of Contents
TH2F
A 2D histogram in ROOT stores how often pairs of values occur together. Instead of counting only a single variable into 1D bins, a 2D histogram has an $x$ axis and a $y$ axis, and each bin corresponds to a small rectangle in the $(x, y)$ plane. The content of each bin is the number (or weight) of events that fall into that range of $x$ and $y$.
The most commonly used 2D histogram class with single precision is TH2F. It stores bin contents as float and is usually sufficient for typical physics analyses where you do not need extremely precise sums in each bin.
A minimal TH2F object is created by giving it a name, a title, and the binning along both axes:
TH2F h2("h2", "Example 2D histogram;X variable;Y variable",
nx, x_min, x_max,
ny, y_min, y_max);The arguments are, in order, the histogram internal name, the displayed title, the number of bins and numeric range for the $x$ axis, and the number of bins and range for the $y$ axis. The semicolons in the title separate the main title, the $x$ axis title, and the $y$ axis title. After creation you typically fill the histogram with pairs of values:
h2.Fill(x_value, y_value);You can then draw the histogram to a canvas:
h2.Draw("COLZ");
The drawing options and detailed display settings are covered elsewhere, so at this stage it is enough to understand that TH2F behaves like a 1D TH1F, but extended to two dimensions with an independent binning for each axis.
TH2F uses single precision float for bin contents. For very large statistics or when you care about small differences in large sums, numerical rounding can accumulate. In those cases prefer TH2D.
You can also create TH2F histograms dynamically with new when you need them to outlive the current scope, for example inside functions or macros:
TH2F *h2ptr = new TH2F("h2ptr", "Title;X;Y",
nx, x_min, x_max,
ny, y_min, y_max);In this case ROOT takes ownership when you assign a directory or write the histogram to a file, but object ownership is a separate topic that is discussed in another chapter.
TH2D
TH2D is the double precision version of a 2D histogram. It has the same interface and behavior as TH2F, but stores bin contents as double. This improves numerical precision for bin contents, errors, and sums.
The typical constructor looks identical, except for the class name:
TH2D h2d("h2d", "High precision 2D histogram;X variable;Y variable",
nx, x_min, x_max,
ny, y_min, y_max);
In most analyses both TH2F and TH2D will produce the same visible plots. The difference is mostly about the internal numeric representation. If you expect very large numbers of entries per bin, or if you accumulate weighted events where each event carries a significant weight, using TH2D avoids loss of precision in the sums.
From the user point of view, filling and drawing a TH2D is the same as for TH2F:
h2d.Fill(x_value, y_value);
h2d.Draw("COLZ");
You can choose between TH2F and TH2D based on memory and precision considerations. TH2D uses more memory because each bin stores a double, but on modern machines this is rarely a limitation unless you use very fine binning or maintain many histograms simultaneously.
Use TH2D when you:
- Accumulate a very large number of entries in each bin, or
- Use significant event weights (for example cross section weights), or
- Need precise integrals and statistical uncertainties from the histogram.
For small or moderate statistics without important weights,TH2Fis usually sufficient.
ROOT also provides other 2D histogram classes such as TH2I and TH2S for integer bin contents, but for analysis work in particle and nuclear physics, TH2F and TH2D are the standard choices.
X and Y binning
For 2D histograms you must specify binning for both axes independently. Each axis can have its own number of bins and numeric range. The simplest case is uniform binning on both axes, which you define with the number of bins and the minimum and maximum values. For example, to define 50 bins from 0 to 10 on the $x$ axis and 40 bins from 0 to 20 on the $y$ axis:
int nx = 50;
double x_min = 0.0;
double x_max = 10.0;
int ny = 40;
double y_min = 0.0;
double y_max = 20.0;
TH2F h2("h2", "Uniform binning;X;Y",
nx, x_min, x_max,
ny, y_min, y_max);
The bin edges are then determined automatically. Each bin has width
$$
\Delta x = \frac{x_{\text{max}} - x_{\text{min}}}{N_x}, \quad
\Delta y = \frac{y_{\text{max}} - y_{\text{min}}}{N_y}.
$$
ROOT also supports nonuniform binning, where bin edges are specified explicitly with arrays. This is useful when the variable has regions of particular interest, for example near a resonance peak, and you want finer bins there and coarser bins elsewhere. To use custom bin edges you provide arrays with the coordinates of the bin boundaries:
const int nx = 4;
double x_edges[nx+1] = {0.0, 1.0, 2.0, 5.0, 10.0};
const int ny = 3;
double y_edges[ny+1] = {0.0, 2.0, 4.0, 10.0};
TH2D h2d("h2d", "Variable binning;X;Y",
nx, x_edges,
ny, y_edges);Here the $x$ axis has 4 bins with edges at 0, 1, 2, 5, and 10, and the $y$ axis has 3 bins with edges at 0, 2, 4, and 10. ROOT will determine the correct bin for each filled point based on these edges.
You can inspect and adjust the binning after creation using axis objects. For a given histogram h2, the x axis is available via h2.GetXaxis() and the y axis via h2.GetYaxis(). Both return TAxis objects that let you query or modify bin properties:
TAxis *xaxis = h2.GetXaxis();
int nxbins = xaxis->GetNbins();
double first_edge = xaxis->GetXmin();
double last_edge = xaxis->GetXmax();You can also change the range of the axis that is displayed without modifying the underlying binning, for example to zoom into a region of interest. This uses bin numbers, not coordinate values:
h2.GetXaxis()->SetRange(xbin_min, xbin_max);
h2.GetYaxis()->SetRange(ybin_min, ybin_max);This visual range selection affects how the histogram is drawn, but the histogram still stores all bins and all data, which is important for later analysis such as projections or integrals.
The choice of binning is always a compromise. Finer binning offers more detail, but fewer entries per bin can lead to larger statistical fluctuations. Coarser binning reduces fluctuations but can hide structure in the data. In 2D several effects are combined, since both axes contribute to the bin size in the plane. When you design a 2D histogram, think carefully about the typical density of points and the features you want to resolve.
Important considerations for 2D binning:
- Choose $N_x$ and $N_y$ so that most bins have a reasonable number of entries. Avoid very large numbers of empty or single entry bins.
- Set the numeric ranges so that relevant data lie inside the histogram, while avoiding excessively large empty regions.
- For variables with strong local structure, consider variable bin widths using explicit edge arrays to keep enough statistics in each bin without losing resolution in interesting regions.
Once you have created the histogram with suitable binning, you can fill it with your data, draw it with appropriate options, and use it for further analysis such as projections or profile histograms, which are covered in later sections.
Views: 12
KAHIBARO