I have a complicated program producing fit plots in PNG format. However, when I try to produce PDF output, the same canvas yields a different image, with some text cropped out. I’ve developed a (near) minimal working example, shown here (code uses C++14 mostly for memory management purposes and compiles with ROOT6):
#include <iostream>
#include <utility>
#include <array>
#include <memory>
#include "TRandom3.h"
#include "TStyle.h"
#include "TH1D.h"
#include "TCanvas.h"
#include "TPad.h"
template<typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args) {
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
std::unique_ptr<TH1D> genHisto(int idx) {
static TRandom3 r;
char name[8]; sprintf(name,"histo_%d",idx);
std::unique_ptr<TH1D> histo = make_unique<TH1D>(name,"",100,-5,5);
for (int i = 0; i < 1000; ++i)
histo->Fill(r.Gaus());
return histo;
}
std::pair< std::unique_ptr<TPad>,std::unique_ptr<TPad> > makeSubpads(int idx) {
const double pad = 0.07;
const double frac = 0.2;
const double gap = 0.01;
char tname[12]; sprintf(tname,"histo_%d_pad",idx);
char bname[12]; sprintf(bname,"ratio_%d_pad",idx);
std::unique_ptr<TPad> padT = make_unique<TPad>(tname, tname, 0.0,pad+frac+gap,1.0,1.0);
std::unique_ptr<TPad> padB = make_unique<TPad>(bname, bname, 0.0,pad,1.0,frac+pad);
return { std::move(padT), std::move(padB) };
}
int main(int,char**) {
// STYLE
const double width = 800;
const double height = 500;
gStyle->SetOptStat(0);
const int font = 133;
gStyle->SetTextFont(font);
gStyle->SetLabelFont(font,"x");
gStyle->SetLabelFont(font,"y");
gStyle->SetTitleFont(font);
gStyle->SetTitleFont(font,"x");
gStyle->SetTitleFont(font,"y");
const double size = 20;
gStyle->SetTextSize(size);
gStyle->SetLabelSize(size,"x");
gStyle->SetLabelSize(size,"y");
gStyle->SetTitleSize(1.2*size,"x");
gStyle->SetTitleSize(1.2*size,"y");
// DATA
const int N = 2;
std::unique_ptr<TH1D> nomHisto = genHisto(0);
std::array<std::unique_ptr<TH1D>,N> histos;
std::array<std::unique_ptr<TH1D>,N> ratios;
for (int i = 0 ; i < N; ++i) {
histos[i] = genHisto(i+1);
ratios[i] = std::unique_ptr<TH1D>(static_cast<TH1D*>(histos[i]->Clone()));
ratios[i]->Divide(nomHisto.get());
ratios[i]->GetYaxis()->SetNdivisions(603);
ratios[i]->SetMinimum(0.0);
ratios[i]->SetMinimum(3.0);
ratios[i]->GetXaxis()->SetTitleOffset(12.0);
ratios[i]->GetXaxis()->SetTitle("TEST LABEL");
}
// SIMPLE PLOT
TCanvas csimple("csimple","csimple",width,height*N);
csimple.Divide(1,N);
for (int i = 0 ; i < N; ++i) {
csimple.cd(i+1);
histos[i]->Draw();
}
csimple.Print("csimple.png");
csimple.Print("csimple.pdf");
// COMPLEX PLOT
TCanvas ccomplex("ccomplex","ccomplex",width,height*N);
ccomplex.SetFillStyle(4000);
ccomplex.Divide(1,N);
std::array<std::pair<std::unique_ptr<TPad>,std::unique_ptr<TPad>>,N> pads;
for (int i = 0 ; i < N; ++i) {
ccomplex.cd(i+1);
pads[i] = makeSubpads(i);
pads[i].first->Draw();
pads[i].second->Draw();
pads[i].first->cd();
histos[i]->Draw();
pads[i].second->cd();
ratios[i]->Draw();
}
ccomplex.Print("ccomplex.png");
ccomplex.Print("ccomplex.pdf");
}
A large x-axis title offset is necessary for a visually appealing separation. This works nicely in the PNG version:
However, in the PDF version this is cut off (PDF exported to a PNG for uploading purposes):
Is there a way to modify this minimal example so that the text is not cut off in the PDF version? It is OK if the geometry of the figure changes slightly, as long there isn’t a noticeable decrease in its quality/appeal.