8.4. Legends
Table of Contents
TLegend
In ROOT, legends are drawn with the class TLegend. A legend is an independent drawable object that lives on the same canvas or pad as your histograms and graphs. It does not know anything about your plot automatically. You explicitly tell it which objects to describe and what text to show.
You usually create a TLegend with coordinates that specify where it appears on the pad. The typical constructor looks like
TLegend *leg = new TLegend(x1, y1, x2, y2);
The four numbers are the lower left and upper right corners of the legend rectangle: (x1, y1) and (x2, y2). By default, these numbers are given in normalized device coordinates, abbreviated NDC. In NDC coordinates, 0 is the left or bottom edge of the pad and 1 is the right or top edge. For example, (0.6, 0.7, 0.9, 0.9) places a legend in the upper right corner of the pad.
You can also change the appearance of the legend itself. The fill color, border, and text size are controlled with the same style methods used for other ROOT objects, such as SetFillColor, SetLineColor, SetBorderSize, and text attribute methods through leg->SetTextSize() and leg->SetTextFont().
Many analyses use a legend without a frame to keep plots clean. You can hide the legend border with
leg->SetBorderSize(0);and remove the background with
leg->SetFillStyle(0);which makes the legend box transparent.
After constructing and configuring the legend, you must add entries that describe your plotted objects and finally draw the legend with
leg->Draw();The legend will then appear on the currently active pad. If you draw additional objects later, ROOT will not update the legend automatically. You must add new entries and redraw or update the pad yourself if the legend content needs to change.
A TLegend does not populate itself. You must:
- Create it in the correct pad or canvas.
- Add entries for each object you want to describe.
- Call
Draw()after the objects have been drawn.
Adding entries
Entries are added to a legend with the AddEntry method. This connects a drawn object, such as a histogram or graph, to a descriptive label and a draw option that controls the icon shown inside the legend.
The most common signature is
leg->AddEntry(object, "label text", "option");
where object is a pointer to a drawable ROOT object, "label text" is the text you want to appear in the legend, and "option" tells ROOT what kind of symbol to show. The option usually matches how the object is drawn. Typical options include:
| Option | Typical use | Icon in legend |
|---|---|---|
"l" | Line plots | Line only |
"p" | Marker plots | Marker only |
"f" | Filled objects such as histograms | Filled box with line color |
"lep" | Line with markers and error bars | Line, marker, and error-bar style |
"le" | Line with error bars | Line and small error decoration |
For example, for a histogram drawn with a line and fill, you could write
TH1F *h1 = new TH1F("h1", "h1", 100, 0, 10);
// fill h1, set styles, draw it
h1->SetLineColor(kRed);
h1->SetFillColor(kRed - 9);
h1->Draw("hist");
TLegend *leg = new TLegend(0.6, 0.7, 0.9, 0.85);
leg->AddEntry(h1, "Signal", "f");
leg->Draw();
The legend will show a small red filled box next to the word "Signal". If another histogram is drawn with a simple outline and no fill, for example with Draw("hist same"), you can associate it with a line entry:
TH1F *h2 = new TH1F("h2", "h2", 100, 0, 10);
// fill h2
h2->SetLineColor(kBlue);
h2->SetFillStyle(0); // no fill
h2->Draw("hist same");
leg->AddEntry(h2, "Background", "l");
You do not need to call Draw() again after adding another entry if the legend is already visible, but the pad must be updated to display the new content. In interactive sessions, this often happens automatically; in macros, especially in batch mode, you may call gPad->Modified(); gPad->Update(); after changing the legend.
The label text can contain LaTeX style expressions interpreted by TLatex, such as "#Delta#phi" or "p_{T} > 20 GeV", so you can match the notation used in particle and nuclear physics.
There is also a variation of AddEntry that uses an object name string instead of a direct pointer. This can be useful when you retrieve objects from a file or from the current directory by name:
leg->AddEntry("h1", "Signal", "f");
Here ROOT looks up "h1" in the current pad or directory when it draws the legend. For beginners, directly passing the pointer is usually simpler and more explicit.
You can control how much space each entry takes by changing the text size or legend margins. Adjusting the legend text size is particularly useful when you need many entries:
leg->SetTextSize(0.03); // smaller text for many lines
Entries are drawn in the order they are added. If you care about the final ordering, add them in that order or use TLegend::GetListOfPrimitives() and reordering methods at a later stage.
When you call AddEntry, make sure:
- The draw option in the legend, like
"l","p", or"f", matches the visual style of the object. - The object pointer or object name passed to
AddEntryrefers to an object that actually exists and is drawn on the same pad.
Positioning legends
Positioning a legend well is essential for clear plots. The legend should explain the data without hiding important structures such as peaks or tails of distributions.
By default, the coordinates passed to the TLegend constructor are interpreted as NDC coordinates. This makes your legend position independent of axis ranges and data values. For most publication style plots, you should use NDC, which is the default. If you need to check or change this behavior, you can call
leg->SetNDC(true);to ensure that the coordinates are normalized inside the pad.
A typical pattern to place a legend in different corners is to pick a fixed legend width and height and then choose coordinates accordingly. For example, with width 0.3 and height 0.2:
| Location | Coordinates example |
|---|---|
| Upper right | (0.60, 0.70, 0.90, 0.90) |
| Upper left | (0.10, 0.70, 0.40, 0.90) |
| Lower right | (0.60, 0.20, 0.90, 0.40) |
| Lower left | (0.10, 0.20, 0.40, 0.40) |
On canvases with multiple pads, always create the legend after selecting the correct pad. Use pad->cd(); or c1->cd(n); before constructing or drawing the legend. Each pad has its own coordinate system. A legend built in one pad will not automatically move or redraw itself if you later switch to a different pad.
Sometimes you need fine control to avoid overlap with plotted data. You can adjust the coordinates by trial and error, or you can let ROOT compute a convenient automatic position relative to the margins. For example, if you have already set margins with a global style, you may want the legend to sit just inside the top right margin:
double x1 = gPad->GetRightMargin() + 0.05;
double y1 = 1.0 - gPad->GetTopMargin() - 0.25;
double x2 = 1.0 - gPad->GetRightMargin();
double y2 = 1.0 - gPad->GetTopMargin();
TLegend *leg = new TLegend(x1, y1, x2, y2);This approach keeps the legend location consistent even if you change axis label sizes and margins.
If the legend hides part of the distribution, a common solution is to move it inside a region where the data density is low, such as the upper right for a peak at low values, or to reduce the text size and legend height. Sometimes you can also make the background transparent and remove the border to see the data underneath while still reading the labels.
On logarithmic axes, the legend coordinates are still in NDC if you use NDC mode. For this reason, placing the legend with NDC is easier than using user coordinates which depend on axis scales.
Finally, remember that a legend is just one more drawable object on the pad. If you draw it before some other objects with Draw("same"), it can end up behind them. The usual practice is to draw all histograms and graphs first, then create the legend, add entries, and draw it at the end to ensure it is visible on top.
To position legends robustly:
- Use NDC coordinates for
TLegendso positions do not change with axis ranges. - Create and draw the legend after selecting the correct pad.
- Draw the legend after all data objects so it appears on top and is easy to read.
Views: 10
KAHIBARO