複数のキャンバスをPDFに保存したい(TCanvas::Print

 1#include <TCanvas.h>
 2#include <TH1D.h>
 3
 4// ファイル名を設定
 5TString filename = "output.pdf";
 6
 7// キャンバスを作成
 8TCanvas *c = new TCanvas("c", "Multi-page PDF", 800, 600);
 9
10// PDFファイルを開く(最初のページ)
11c->Print(filename + "[", "pdf");
12
13// 複数のヒストグラムを描画して保存
14for (Int_t i = 0; i < 3; i++) {
15    TH1D *h = new TH1D(Form("h%d", i), Form("Histogram %d", i), 100, -3, 3);
16    h->FillRandom("gaus", 1000);
17    h->Draw();
18
19    // PDFにページを追加
20    c->Print(filename, "pdf");
21}
22
23// PDFファイルを閉じる
24c->Print(filename + "]", "pdf");

TCanvas::Printメソッドを使って、複数のページを1つのPDFファイルに保存できます。 PDF形式ではページ開始記号[と終了記号]を使うことで、複数のキャンバスを同じファイルに追記できます。

 1from ROOT import TCanvas, TH1D
 2
 3filename = "output.pdf"
 4
 5c = TCanvas("c", "Multi-page PDF", 800, 600)
 6
 7# PDFファイルを開く
 8c.Print(filename + "[", "pdf")
 9
10# 複数のページを追加
11for i in range(3):
12    h = TH1D(f"h{i}", f"Histogram {i}", 100, -3, 3)
13    h.FillRandom("gaus", 1000)
14    h.Draw()
15    c.Print(filename, "pdf")
16
17# PDFファイルを閉じる
18c.Print(filename + "]", "pdf")

メソッドのシグネチャ

1void Print(const char *filename = "", Option_t *option = "")

引数と戻り値

引数:

  • filename - 出力ファイルパス。PDFマルチページの場合:

    • filename + "[" - PDFファイルを開く(最初のページ)

    • filename - PDFにページを追加

    • filename + "]" - PDFファイルを閉じる

  • option - 出力形式("pdf""ps"など)

PDFマルチページの基本パターン

ページ開始・追加・終了の記号

記号

説明

使用例

[

PDFファイルを開く(最初のページは出力しない)

filename + "["

(通常)

現在のキャンバスをページとして追加

filename

]

PDFファイルを閉じる

filename + "]"

記号の重要性

  • [ を使わないと、その時点でページが出力される

  • ] を使うことで、PDFファイルが確実に閉じられる

  • 複数の [] を使うと、エラーが発生する可能性がある

使用例

複数のヒストグラムを1つのPDFに保存したい

 1#include <TCanvas.h>
 2#include <TH1D.h>
 3#include <TRandom.h>
 4
 5TCanvas *c = new TCanvas("c", "Analysis Results", 800, 600);
 6
 7TString filename = "analysis.pdf";
 8
 9// PDFファイルを開く
10c->Print(filename + "[", "pdf");
11
12// 複数のヒストグラムを描画して保存
13for (Int_t i = 0; i < 5; i++) {
14    TH1D *h = new TH1D(Form("h%d", i), Form("Dataset %d", i), 100, -5, 5);
15
16    // ガウス分布でデータを埋める
17    for (Int_t j = 0; j < 10000; j++) {
18        h->Fill(gRandom->Gaus(0, 1));
19    }
20
21    h->Draw();
22    c->Print(filename, "pdf");  // ページを追加
23}
24
25// PDFファイルを閉じる
26c->Print(filename + "]", "pdf");

複数のヒストグラムを順番に描画し、各々をPDFの新しいページとして保存します。

複数のキャンバスから異なるオブジェクトを保存したい

 1#include <TCanvas.h>
 2#include <TGraph.h>
 3#include <TH2D.h>
 4
 5TString filename = "mixed_objects.pdf";
 6
 7// 1番目のキャンバス:ヒストグラム
 8TCanvas *c1 = new TCanvas("c1", "Canvas 1", 800, 600);
 9c1->Print(filename + "[", "pdf");
10
11TH1D *h = new TH1D("h", "Histogram", 100, -3, 3);
12h->FillRandom("gaus", 5000);
13h->Draw();
14c1->Print(filename, "pdf");
15
16// 2番目のキャンバス:グラフ
17TCanvas *c2 = new TCanvas("c2", "Canvas 2", 800, 600);
18TGraph *g = new TGraph();
19for (Int_t i = 0; i < 100; i++) {
20    g->SetPoint(i, i, sin(i * 0.1));
21}
22g->Draw("AL");
23c2->Print(filename, "pdf");
24
25// 3番目のキャンバス:2次元ヒストグラム
26TCanvas *c3 = new TCanvas("c3", "Canvas 3", 800, 600);
27TH2D *h2 = new TH2D("h2", "2D Histogram", 50, -3, 3, 50, -3, 3);
28for (Int_t i = 0; i < 10000; i++) {
29    h2->Fill(gRandom->Gaus(), gRandom->Gaus());
30}
31h2->Draw("colz");
32c3->Print(filename, "pdf");
33
34// PDFファイルを閉じる
35c3->Print(filename + "]", "pdf");

異なるキャンバスや異なるオブジェクト(ヒストグラム、グラフ、2次元ヒストグラムなど)を同じPDFに保存できます。

ループで大量のページを生成したい

 1#include <TCanvas.h>
 2#include <TH1D.h>
 3#include <TRandom.h>
 4
 5TString filename = "large_pdf.pdf";
 6TCanvas *c = new TCanvas("c", "Large PDF", 800, 600);
 7
 8c->Print(filename + "[", "pdf");
 9
10// 100ページ分のヒストグラムを生成
11for (Int_t page = 0; page < 100; page++) {
12    TH1D *h = new TH1D(Form("h%d", page),
13                       Form("Page %d - Distribution", page),
14                       100, -5, 5);
15
16    // 異なる平均値でデータを生成
17    Double_t mean = -5 + page * 0.1;
18    for (Int_t i = 0; i < 5000; i++) {
19        h->Fill(gRandom->Gaus(mean, 1));
20    }
21
22    h->Draw();
23    c->Print(filename, "pdf");
24
25    // メモリ管理:前のヒストグラムを削除
26    delete h;
27}
28
29c->Print(filename + "]", "pdf");
30
31std::cout << "PDF file created: " << filename << std::endl;

ループを使って大量のページを効率的に生成できます。 メモリ管理を適切に行うことで、スムーズな処理が実現します。

PostScript形式で複数ページを保存したい

 1#include <TCanvas.h>
 2#include <TH1D.h>
 3
 4TString filename = "output.ps";
 5TCanvas *c = new TCanvas("c", "PostScript Output", 800, 600);
 6
 7// PostScript形式で開始
 8c->Print(filename + "[", "ps");
 9
10// 複数のページを追加
11for (Int_t i = 0; i < 3; i++) {
12    TH1D *h = new TH1D(Form("h%d", i), Form("Page %d", i), 100, 0, 10);
13    h->FillRandom("gaus", 1000);
14    h->Draw();
15    c->Print(filename, "ps");
16}
17
18// PostScript形式で終了
19c->Print(filename + "]", "ps");

PDFと同様に、PostScript形式でも複数ページの出力がサポートされています。

トラブルシューティング

PDFが開けない、または破損している場合

1// 最初と最後の記号が正確に対応していることを確認
2c->Print("output.pdf" + "[", "pdf");   // OK: 開始
3// ... 処理 ...
4c->Print("output.pdf" + "]", "pdf");   // OK: 終了
5
6// ❌ 間違い: 記号が逆
7// c->Print("output.pdf" + "]", "pdf");
8// c->Print("output.pdf" + "[", "pdf");

複数のファイルに分割したい場合

 1// 複数のPDFファイルを作成する場合
 2for (Int_t file = 0; file < 3; file++) {
 3    TString filename;
 4    filename.Form("output_%d.pdf", file);
 5
 6    TCanvas *c = new TCanvas(Form("c%d", file), "", 800, 600);
 7    c->Print(filename + "[", "pdf");
 8
 9    for (Int_t page = 0; page < 10; page++) {
10        TH1D *h = new TH1D(Form("h%d", page), "", 100, 0, 10);
11        h->FillRandom("gaus", 1000);
12        h->Draw();
13        c->Print(filename, "pdf");
14    }
15
16    c->Print(filename + "]", "pdf");
17}

関連メソッド

参考資料