9Bool_t PlottingUtils::preferences_set_ = kFALSE;
10Width_t PlottingUtils::line_width_ = 2;
11TString PlottingUtils::plots_base_dir_ =
"plots";
15 while (d.Length() > 0 && d[d.Length() - 1] ==
'/')
22void PlottingUtils::WarnIfNotConfigured(
const TString method_name) {
23 if (!preferences_set_)
24 std::cout <<
"WARNING: " << method_name
25 <<
" called before SetStylePreferences()." << std::endl;
29 save_format_ = save_format;
30 preferences_set_ = kTRUE;
33 gStyle->SetOptStat(0);
35 gStyle->SetPadLeftMargin(0.15);
36 gStyle->SetPadRightMargin(0.1);
37 gStyle->SetPadTopMargin(0.12);
38 gStyle->SetPadBottomMargin(0.15);
39 gStyle->SetTitleSize(0.06,
"XY");
40 gStyle->SetLabelSize(0.06,
"XY");
41 gStyle->SetLegendFont(132);
42 gStyle->SetTitleOffset(1.2,
"X");
43 gStyle->SetTitleOffset(1.2,
"Y");
44 gStyle->SetTextFont(42);
45 gStyle->SetHistLineWidth(line_width_);
46 gStyle->SetLineWidth(line_width_);
47 gStyle->SetPadGridX(1);
48 gStyle->SetPadGridY(1);
49 gStyle->SetGridStyle(3);
50 gStyle->SetGridWidth(line_width_);
51 gStyle->SetGridColor(kGray);
52 gStyle->SetPadTickX(1);
53 gStyle->SetPadTickY(1);
59 const TString title) {
60 WarnIfNotConfigured(
"ConfigureGraph");
61 graph->SetLineColor(color);
62 graph->SetTitle(title);
63 graph->GetXaxis()->SetTitleSize(0.06);
64 graph->GetYaxis()->SetTitleSize(0.06);
65 graph->GetXaxis()->SetLabelSize(0.06);
66 graph->GetYaxis()->SetLabelSize(0.06);
67 graph->GetXaxis()->SetTitleOffset(1.2);
68 graph->GetYaxis()->SetTitleOffset(1.2);
69 graph->GetXaxis()->SetNdivisions(506);
70 graph->SetLineWidth(line_width_);
74 const TString title) {
75 WarnIfNotConfigured(
"ConfigureGraph");
76 graph->SetLineColor(color);
77 graph->SetTitle(title);
78 graph->GetXaxis()->SetTitleSize(0.06);
79 graph->GetYaxis()->SetTitleSize(0.06);
80 graph->GetXaxis()->SetLabelSize(0.06);
81 graph->GetYaxis()->SetLabelSize(0.06);
82 graph->GetXaxis()->SetTitleOffset(1.2);
83 graph->GetYaxis()->SetTitleOffset(1.2);
84 graph->GetXaxis()->SetNdivisions(506);
85 graph->SetMarkerStyle(20);
86 graph->SetMarkerSize(1.2);
87 graph->SetMarkerColor(color);
88 graph->SetLineWidth(line_width_);
92 const TString title) {
95 WarnIfNotConfigured(
"ConfigureHistogram");
97 hist->SetLineColor(color);
98 hist->SetTitle(title);
99 hist->SetLineWidth(line_width_);
100 hist->SetFillStyle(0);
101 hist->GetYaxis()->SetMoreLogLabels(kFALSE);
102 hist->GetYaxis()->SetNoExponent(kFALSE);
103 hist->GetXaxis()->SetNoExponent(kTRUE);
104 hist->GetYaxis()->SetNdivisions(50109);
105 hist->GetXaxis()->SetNdivisions(505);
106 hist->GetXaxis()->SetTitleSize(0.06);
107 hist->GetYaxis()->SetTitleSize(0.06);
108 hist->GetXaxis()->SetLabelSize(0.06);
109 hist->GetYaxis()->SetLabelSize(0.06);
110 hist->GetXaxis()->SetTitleOffset(1.2);
111 hist->GetYaxis()->SetTitleOffset(1.2);
115 const TString title) {
120 WarnIfNotConfigured(
"Configure2DHistogram");
122 hist->SetTitle(title);
123 hist->GetYaxis()->SetMoreLogLabels(kFALSE);
124 hist->GetYaxis()->SetNoExponent(kFALSE);
125 hist->GetXaxis()->SetTitleSize(0.06);
126 hist->GetYaxis()->SetTitleSize(0.06);
127 hist->GetXaxis()->SetLabelSize(0.06);
128 hist->GetYaxis()->SetLabelSize(0.06);
129 hist->GetXaxis()->SetTitleOffset(1.2);
130 hist->GetYaxis()->SetTitleOffset(1);
131 hist->GetXaxis()->SetNdivisions(506);
132 hist->GetYaxis()->SetNdivisions(506);
134 canvas->SetLogz(kTRUE);
135 canvas->SetRightMargin(0.15);
139 const TString title) {
148 const TString title) {
157 const TString title) {
168 WarnIfNotConfigured(
"GetConfiguredCanvas");
169 TCanvas *canvas =
new TCanvas(
GetRandomName(),
"", 1200, 800);
173 canvas->SetLogy(logy);
175 canvas->SetTicks(1, 1);
176 gPad->SetTicks(1, 1);
183 Int_t legend_width_px,
184 Int_t plot_height_px,
186 WarnIfNotConfigured(
"GetConfiguredCanvasWithSideLegend");
187 const Int_t plot_width_px = 1200;
188 const Int_t canvas_width_px = plot_width_px + TMath::Max(0, legend_width_px);
190 new TCanvas(
GetRandomName(),
"", canvas_width_px, plot_height_px);
191 canvas->SetTicks(1, 1);
192 const Double_t split = Double_t(plot_width_px) / Double_t(canvas_width_px);
196 plot->SetTicks(1, 1);
198 const Double_t frame_right = split * (1.0 - plot->GetRightMargin());
199 legend_pad =
new TPad(
GetRandomName(),
"", frame_right, 0.0, 1.0, 1.0);
200 legend_pad->SetFillStyle(4000);
201 legend_pad->SetMargin(0.0, 0.0, 0.0, 0.0);
209 TPad *&upper, TPad *&lower) {
212 if (!pad || !pad->GetCanvas())
214 const Double_t pad_height_px = pad->GetCanvas()->GetWh() * pad->GetAbsHNDC();
215 if (!(pad_height_px > 0.0) || panel_height_px <= 0 ||
216 panel_height_px >= pad_height_px)
218 const Double_t upper_height_px = pad_height_px - panel_height_px;
219 const Double_t split = Double_t(panel_height_px) / pad_height_px;
220 const Double_t lower_top =
221 (panel_height_px + pad->GetBottomMargin() * upper_height_px) /
223 TVirtualPad *previous = gPad;
226 upper->SetLeftMargin(pad->GetLeftMargin());
227 upper->SetRightMargin(pad->GetRightMargin());
228 upper->SetTopMargin(pad->GetTopMargin());
229 upper->SetBottomMargin(pad->GetBottomMargin());
230 upper->SetGridx(pad->GetGridx());
231 upper->SetGridy(pad->GetGridy());
232 upper->SetTicks(pad->GetTickx(), pad->GetTicky());
233 upper->SetLogy(pad->GetLogy());
234 lower =
new TPad(
GetRandomName(),
"", 0.0, 0.0, 1.0, lower_top);
235 lower->SetFillStyle(4000);
236 lower->SetLeftMargin(pad->GetLeftMargin());
237 lower->SetRightMargin(pad->GetRightMargin());
238 lower->SetTopMargin(0.03);
239 lower->SetBottomMargin(pad->GetBottomMargin());
240 lower->SetGridx(pad->GetGridx());
241 lower->SetGridy(pad->GetGridy());
242 lower->SetTicks(pad->GetTickx(), pad->GetTicky());
250 TString output_subdirectory,
252 WarnIfNotConfigured(
"SaveFigure");
253 canvas->SetLogy(kFALSE);
258 TString output_filename = output_name + extension;
262 output_subdirectory ==
"" ? base : base +
"/" + output_subdirectory;
264 if (gSystem->AccessPathName(full_dir)) {
265 gSystem->mkdir(full_dir, kTRUE);
268 TString prefix = full_dir +
"/";
273 TString print_option =
277 canvas->Print(prefix + output_filename, print_option);
280 TList *primitives = canvas->GetListOfPrimitives();
281 Int_t size = primitives->GetSize();
283 for (Int_t i = 0; i < size; i++) {
284 TObject *
object = primitives->At(i);
285 if (object->InheritsFrom(TH2::Class())) {
286 std::cout << std::endl;
287 std::cerr <<
"ERROR: Used PlotSaveOptions::kLOG for 2D histogram."
290 <<
"This option is exclusive to 1D histograms/graphs because it refers to the y axis."
292 std::cout <<
"Use PlotSaveOptions::kLINEAR." << std::endl;
294 <<
"The z axis is already log by default if you used PlottingUtils::Configure2DHistogram()."
296 std::cout <<
"Plot " << prefix +
"log_" + output_filename
297 <<
" was not saved." << std::endl;
302 canvas->SetLogy(kTRUE);
305 canvas->Print(prefix +
"log_" + output_filename, print_option);
307 canvas->SetLogy(kFALSE);
314 return {kRed + 1, kBlue + 1, kGreen + 2, kOrange + 1, kMagenta + 1,
315 kCyan + 2, kViolet + 1, kSpring - 1, kPink + 1, kTeal + 2,
316 kAzure + 2, kYellow + 1, kOrange - 3, kMagenta - 3, kCyan - 6,
317 kRed - 4, kBlue - 4, kGreen - 6, kViolet - 4, kSpring + 5,
318 kPink - 3, kTeal - 5, kAzure - 3, kOrange + 7};
323 TLegend *leg =
new TLegend(x1, y1, x2, y2);
324 leg->SetBorderSize(1);
325 leg->SetFillColor(kWhite);
326 leg->SetTextSize(30);
327 leg->SetTextFont(43);
335 if (text.Length() == 0)
337 TVirtualPad *previous = gPad;
338 const Int_t scratch_px = 1000;
339 TCanvas *scratch =
new TCanvas(
GetRandomName(),
"", scratch_px, scratch_px);
340 TLatex latex(0.1, 0.5, text);
342 latex.SetTextFont(font);
343 latex.SetTextSize(size_px);
344 const Double_t width_px = latex.GetXsize() * scratch_px;
352 const TString &header, Double_t size_px,
353 Double_t margin, Double_t padding_px) {
355 for (std::size_t i = 0; i < labels.size(); i++)
356 width_px = TMath::Max(width_px,
TextWidthPx(labels[i], size_px) /
357 TMath::Max(0.05, 1.0 - margin));
358 return width_px + 2.0 * padding_px;
362 Int_t reference_width_px) {
363 if (!pad || !pad->GetCanvas() || reference_width_px <= 0)
365 const Double_t pad_width_px = pad->GetCanvas()->GetWw() * pad->GetAbsWNDC();
366 return pad_width_px / Double_t(reference_width_px);
370 Int_t reference_height_px) {
371 WarnIfNotConfigured(
"ScaleFigure");
375 reference_height_px);
379 Int_t reference_width_px,
380 Int_t reference_height_px) {
381 if (!pad || !pad->GetCanvas())
383 const Double_t pad_width_px = pad->GetCanvas()->GetWw() * pad->GetAbsWNDC();
384 const Double_t pad_height_px = pad->GetCanvas()->GetWh() * pad->GetAbsHNDC();
385 if (!(pad_width_px > 0.0) || !(pad_height_px > 0.0))
387 const Double_t x_factor = reference_width_px * scale / pad_width_px;
388 const Double_t y_factor = reference_height_px * scale / pad_height_px;
389 pad->SetLeftMargin(TMath::Min(0.9, pad->GetLeftMargin() * x_factor));
390 pad->SetRightMargin(TMath::Min(0.9, pad->GetRightMargin() * x_factor));
391 pad->SetTopMargin(TMath::Min(0.9, pad->GetTopMargin() * y_factor));
392 pad->SetBottomMargin(TMath::Min(0.9, pad->GetBottomMargin() * y_factor));
394 TList *primitives = pad->GetListOfPrimitives();
397 TIter next(primitives);
398 for (TObject *
object = next(); object;
object = next()) {
399 if (object->InheritsFrom(TVirtualPad::Class())) {
400 ScalePad(
static_cast<TVirtualPad *
>(
object), scale, reference_width_px,
401 reference_height_px);
404 if (object->InheritsFrom(TLegend::Class())) {
405 ScaleLegend(
static_cast<TLegend *
>(
object), scale);
408 if (object->InheritsFrom(TText::Class())) {
409 ScaleText(
static_cast<TText *
>(
object), pad, scale, reference_height_px);
412 if (object->InheritsFrom(TH1::Class()))
414 reference_width_px, reference_height_px);
415 ScaleLine(
dynamic_cast<TAttLine *
>(
object), scale);
416 ScaleMarker(
dynamic_cast<TAttMarker *
>(
object), scale);
422 Int_t reference_width_px,
423 Int_t reference_height_px) {
424 WarnIfNotConfigured(
"ScaleAxisFontsToPad");
425 if (!frame || !pad || !pad->GetCanvas() || reference_width_px <= 0 ||
426 reference_height_px <= 0)
428 const Double_t pad_width_px = pad->GetCanvas()->GetWw() * pad->GetAbsWNDC();
429 const Double_t pad_height_px = pad->GetCanvas()->GetWh() * pad->GetAbsHNDC();
430 const Double_t pad_px = TMath::Min(pad_width_px, pad_height_px);
433 const Double_t size = 0.06 * reference_height_px * scale / pad_px;
434 const Double_t reference_aspect =
435 Double_t(TMath::Min(reference_width_px, reference_height_px)) /
436 Double_t(reference_width_px);
437 TAxis *axes[2] = {frame->GetXaxis(), frame->GetYaxis()};
438 for (Int_t i = 0; i < 2; i++) {
439 if (axes[i]->GetTitleSize() > 0.0)
440 axes[i]->SetTitleSize(size);
441 if (axes[i]->GetLabelSize() > 0.0)
442 axes[i]->SetLabelSize(size);
444 frame->GetXaxis()->SetTitleOffset(1.2 * pad_px / pad_height_px);
445 frame->GetYaxis()->SetTitleOffset(1.2 * (pad_px / pad_width_px) /
452 legend->SetTextSize(30.0 * scale);
456 Int_t reference_height_px) {
457 if (!text || !pad || !pad->GetCanvas())
459 const Int_t precision = text->GetTextFont() % 10;
460 if (precision == 3) {
461 text->SetTextSize(text->GetTextSize() * scale);
464 const Double_t pad_width_px = pad->GetCanvas()->GetWw() * pad->GetAbsWNDC();
465 const Double_t pad_height_px = pad->GetCanvas()->GetWh() * pad->GetAbsHNDC();
466 const Double_t pad_px = TMath::Min(pad_width_px, pad_height_px);
469 text->SetTextSize(text->GetTextSize() * reference_height_px * scale / pad_px);
474 if (!pad || title.Length() == 0)
476 TVirtualPad *previous = gPad;
478 TLatex *text =
new TLatex(0.5, 1.0 - 0.5 * pad->GetTopMargin(), title);
480 text->SetTextFont(43);
481 text->SetTextSize(36.0 * scale);
482 text->SetTextAlign(22);
490 if (!line || line->GetLineWidth() == 0)
493 Width_t(TMath::Max(1, TMath::Nint(line->GetLineWidth() * scale))));
499 marker->SetMarkerSize(marker->GetMarkerSize() * scale);
504 TLatex *text =
new TLatex(x, y, label);
506 text->SetTextSize(30);
507 text->SetTextAlign(33);
508 text->SetTextFont(43);
509 text->SetTextAngle(angle);
516 static TRandom3 generator(0);
517 Double_t number = generator.Rndm();
518 TString name = Form(
"name%.7f", number);
523 TH1 *hist, TGraph *total_graph,
524 const std::vector<TGraph *> &component_graphs, Float_t fit_range_low,
525 Float_t fit_range_high,
const TString &output_name,
526 const TString &output_subdirectory,
const TString &label, Bool_t logy) {
529 TPad *pad1 =
new TPad(
"pad1",
"pad1", 0, 0.3, 1, 1.0);
530 TPad *pad2 =
new TPad(
"pad2",
"pad2", 0, 0, 1, 0.3);
531 pad1->SetBottomMargin(0.04);
534 pad1->SetTopMargin(0.12);
535 pad2->SetTopMargin(0.04);
536 pad2->SetBottomMargin(0.35);
543 Float_t min_hist_value = 0.9 * fit_range_low;
544 Float_t max_hist_value = 1.1 * fit_range_high;
546 hist->GetXaxis()->SetRangeUser(min_hist_value, max_hist_value);
547 hist->GetXaxis()->SetLabelSize(0);
548 hist->GetXaxis()->SetTitleSize(0);
549 hist->SetLineColor(kViolet);
550 hist->GetYaxis()->SetTitleOffset(1);
551 hist->SetLineWidth(line_width_);
556 total_graph->Draw(
"L same");
557 for (std::size_t i = 0; i < component_graphs.size(); i++) {
558 if (component_graphs[i])
559 component_graphs[i]->Draw(
"L same");
564 Int_t nbins = hist->GetNbinsX();
565 TGraph *residuals =
new TGraph();
566 Int_t point_counter = 0;
567 for (Int_t i = 1; i <= nbins; i++) {
568 Double_t x = hist->GetBinCenter(i);
569 if (x < fit_range_low || x > fit_range_high)
571 Double_t data = hist->GetBinContent(i);
572 Double_t fit_val = total_graph ? total_graph->Eval(x) : 0.0;
573 Double_t error = hist->GetBinError(i);
575 if (error > 0 && data > 0) {
576 Double_t pull = (data - fit_val) / error;
577 residuals->SetPoint(point_counter, x, pull);
582 residuals->SetMarkerStyle(20);
583 residuals->SetMarkerSize(0.8);
584 residuals->SetMarkerColor(kAzure);
585 residuals->SetLineColor(kAzure);
586 residuals->SetTitle(
"");
587 Double_t actual_min =
588 hist->GetXaxis()->GetBinLowEdge(hist->GetXaxis()->GetFirst());
589 Double_t actual_max =
590 hist->GetXaxis()->GetBinUpEdge(hist->GetXaxis()->GetLast());
591 residuals->GetXaxis()->SetLimits(actual_min, actual_max);
592 residuals->GetYaxis()->SetTitle(
"#delta/#sigma");
593 residuals->GetXaxis()->SetTitle(hist->GetXaxis()->GetTitle());
594 residuals->GetXaxis()->SetTitleSize(0.13);
595 residuals->GetYaxis()->SetTitleSize(0.13);
596 residuals->GetXaxis()->SetLabelSize(0.12);
597 residuals->GetYaxis()->SetLabelSize(0.12);
598 residuals->GetXaxis()->SetTitleOffset(1.0);
599 residuals->GetYaxis()->SetTitleOffset(0.3);
600 residuals->GetYaxis()->SetNdivisions(505);
601 residuals->GetXaxis()->SetNdivisions(510);
602 residuals->GetYaxis()->CenterTitle(kTRUE);
603 residuals->GetYaxis()->SetRangeUser(-5.5, 5.5);
604 residuals->Draw(
"AP");
606 TF1 *zero_line =
new TF1(
"zero_line",
"0", actual_min, actual_max);
607 zero_line->SetLineColor(kBlack);
608 zero_line->SetLineStyle(2);
609 zero_line->SetLineWidth(line_width_);
610 zero_line->Draw(
"same");
612 TF1 *plus3_line =
new TF1(
"plus3_line",
"3", actual_min, actual_max);
613 plus3_line->SetLineColor(kGray + 2);
614 plus3_line->SetLineStyle(3);
615 plus3_line->SetLineWidth(line_width_);
616 plus3_line->Draw(
"same");
618 TF1 *minus3_line =
new TF1(
"minus3_line",
"-3", actual_min, actual_max);
619 minus3_line->SetLineColor(kGray + 2);
620 minus3_line->SetLineStyle(3);
621 minus3_line->SetLineWidth(line_width_);
622 minus3_line->Draw(
"same");
626 if (label.Length() > 0) {
632 SaveFigure(canvas, output_name, output_subdirectory, save_opts);
634 PlotPullHistogram(residuals, output_name, output_subdirectory);
636 gROOT->GetListOfCanvases()->Remove(canvas);
637 canvas->SetBatch(kTRUE);
645void PlottingUtils::PlotPullHistogram(TGraph *residuals,
646 const TString &output_name,
647 const TString &output_subdirectory) {
648 Int_t npoints = residuals->GetN();
653 new TH1D(
"pull_hist",
";#delta/#sigma;Counts", 82, -5.5, 5.5);
655 Double_t *y = residuals->GetY();
656 for (Int_t i = 0; i < npoints; i++) {
657 pull_hist->Fill(y[i]);
660 TH1D *gauss_ref =
new TH1D(
"gauss_ref",
"", 82, -5.5, 5.5);
661 for (Int_t i = 1; i <= gauss_ref->GetNbinsX(); i++) {
662 Double_t lo = gauss_ref->GetBinLowEdge(i);
663 Double_t hi = lo + gauss_ref->GetBinWidth(i);
664 gauss_ref->SetBinContent(i, npoints * (TMath::Freq(hi) - TMath::Freq(lo)));
667 Double_t ks_pvalue = pull_hist->KolmogorovTest(gauss_ref);
671 AddText(TString::Format(
"KS p = %.3f", ks_pvalue), 0.85, 0.85);
673 SaveFigure(hist_canvas,
"residuals_" + output_name,
681void PlottingUtils::SetTurboPalette() {
682 Int_t N_COLORS = 255;
684 std::vector<Double_t> stops(N_COLORS);
685 std::vector<Double_t> reds(N_COLORS);
686 std::vector<Double_t> greens(N_COLORS);
687 std::vector<Double_t> blues(N_COLORS);
689 for (Int_t i = 0; i < N_COLORS; ++i) {
690 Double_t x = Double_t(i) / Double_t(N_COLORS - 1);
692 Double_t r = 0.13572138 + 4.61539260 * x - 42.66032258 * x * x +
693 132.13108234 * x * x * x - 152.94239396 * x * x * x * x +
694 59.28637943 * x * x * x * x * x;
696 Double_t g = 0.09140261 + 2.19418839 * x + 4.84296658 * x * x -
697 14.18503333 * x * x * x + 4.27729857 * x * x * x * x +
698 2.82956604 * x * x * x * x * x;
700 Double_t b = 0.10667330 + 12.64194608 * x - 60.58204836 * x * x +
701 110.36276771 * x * x * x - 89.90310912 * x * x * x * x +
702 27.34824973 * x * x * x * x * x;
705 reds[i] = std::max(0.0, std::min(1.0, r));
706 greens[i] = std::max(0.0, std::min(1.0, g));
707 blues[i] = std::max(0.0, std::min(1.0, b));
711 TColor::CreateGradientColorTable(N_COLORS, stops.data(), reds.data(),
712 greens.data(), blues.data(), N_COLORS);
714 std::vector<Int_t> palette(N_COLORS);
715 for (Int_t i = 0; i < N_COLORS; ++i) {
716 palette[i] = firstColor + i;
719 gStyle->SetNumberContours(N_COLORS);
720 gStyle->SetPalette(N_COLORS, palette.data());
PlotSaveOptions
Which axis scalings SaveFigure() should write out.
@ kLOG
Logarithmic y only, written with a log_ filename prefix.
PlotSaveFormat
Output file format for saved figures.
@ kPNG
PNG raster output; line width 2.
@ kPDF
PDF vector output; line width 1.
static TLatex * AddText(const TString label, Double_t x=0.9, Double_t y=0.85, Double_t angle=0)
Create and draw a text annotation on the current pad.
static void ConfigureAndDrawGraph(TGraph *graph, Int_t color, const TString title="")
ConfigureGraph() followed by Draw().
static TLegend * AddLegend(Double_t x1=0.7, Double_t x2=0.9, Double_t y1=0.7, Double_t y2=0.9)
Create, style and draw a legend on the current pad.
static void SaveFigure(TCanvas *canvas, TString output_filename, TString output_subdirectory="", PlotSaveOptions save_options=PlotSaveOptions::kBOTH)
Write a canvas to disk under the configured plots base directory.
static void SetPlotsBaseDir(const TString &dir)
Set the base directory that saved figures are written under.
static TString GetRandomName()
Generate a name unlikely to collide with existing ROOT objects.
static TLatex * DrawTitle(TVirtualPad *pad, const TString &title, Double_t scale=1.0)
Draw a figure title centred in a pad's top margin, at the size ROOT's own pad title has on the standa...
static void ConfigureGraph(TGraph *graph, Int_t color, const TString title="")
Apply the preferred style to a graph without drawing it.
static void ScaleLegend(TLegend *legend, Double_t scale)
Set a legend's text to AddLegend()'s 30 px times a scale.
static void SetStylePreferences(PlotSaveFormat save_format=PlotSaveFormat::kPNG)
Install the global ROOT style and choose the output format.
static void Configure2DHistogram(TH2 *hist, TCanvas *canvas, const TString title="")
Apply the preferred style to a 2-D histogram and its canvas.
static void ConfigureAndDrawHistogram(TH1 *hist, Int_t color, const TString title="")
ConfigureHistogram() followed by Draw("HIST").
static void ConfigureHistogram(TH1 *hist, Int_t color, const TString title="")
Apply the preferred style to a 1-D histogram without drawing it.
static TCanvas * GetConfiguredCanvasWithSideLegend(TPad *&plot, TPad *&legend_pad, Int_t legend_width_px=600, Int_t plot_height_px=800, Bool_t logy=kFALSE)
A canvas with the standard plot area and a legend pad to its right.
static Double_t LegendWidthPx(const std::vector< TString > &labels, const TString &header="", Double_t size_px=30.0, Double_t margin=0.25, Double_t padding_px=15.0)
Width a legend box needs for its labels at AddLegend()'s font.
static TCanvas * GetConfiguredCanvas(Bool_t logy=kFALSE)
Create a 1200x800 canvas with grid and ticks already set up.
static Double_t FigureScale(TVirtualPad *pad, Int_t reference_width_px=1200)
How much larger a pad is than the standard plot area, by width.
static void ScaleLine(TAttLine *line, Double_t scale)
Multiply a line width by a scale, rounded to a whole pixel.
static void ScaleText(TText *text, TVirtualPad *pad, Double_t scale, Int_t reference_height_px=800)
Scale a text object with its pad.
static void SplitPadForPanel(TVirtualPad *pad, Int_t panel_height_px, TPad *&upper, TPad *&lower)
Split a pad into a main pad above and a panel below, leaving the main pad's frame exactly as it would...
static Double_t TextWidthPx(const TString &text, Double_t size_px=30.0, Int_t font=43)
Rendered width of a text in a pixel-sized font.
static void PlotFitWithResiduals(TH1 *hist, TGraph *total_graph, const std::vector< TGraph * > &component_graphs, Float_t fit_range_low, Float_t fit_range_high, const TString &output_name, const TString &output_subdirectory="fits", const TString &label="", Bool_t logy=kTRUE)
Draw a fit over its data with a residual panel and save it.
static std::vector< Int_t > GetDefaultColors()
A palette of visually distinct ROOT colour indices.
static void ScaleFigure(TVirtualPad *pad, Int_t reference_width_px=1200, Int_t reference_height_px=800)
Scale everything on a pad, and its sub-pads, to print like the standard figure.
static void ScaleAxisFontsToPad(TH1 *frame, TVirtualPad *pad, Double_t scale=1.0, Int_t reference_width_px=1200, Int_t reference_height_px=800)
Size a frame's axis text as on the standard canvas, times a scale.
static void ScalePad(TVirtualPad *pad, Double_t scale, Int_t reference_width_px=1200, Int_t reference_height_px=800)
Scale one pad and everything drawn on it, recursively.
static void ScaleMarker(TAttMarker *marker, Double_t scale)
Multiply a marker size by a scale.
static void ConfigureAndDraw2DHistogram(TH2 *hist, TCanvas *canvas, const TString title="")
Configure2DHistogram() followed by Draw("COLZ").
static TString GetPlotsBaseDir()
Current base directory for saved figures, without trailing slash.