キャンバスを分割したい(TCanvas::Divide

 1#include <TCanvas.h>
 2#include <TH1D.h>
 3
 4// キャンバスを作成
 5TCanvas *c = new TCanvas("c", "Divided Canvas", 1200, 800);
 6
 7// キャンバスを2×3に分割(6つの領域)
 8c->Divide(2, 3);
 9
10// 5番目の領域に描画する場合
11c->cd(5);

TCanvas::Divideメソッドでキャンバスを複数の領域に分割できます。 TCanvas::cdメソッドで描画対象の領域を選択します。 これにより、複数のグラフやヒストグラムを1つのキャンバスに同時に表示できます。

 1from ROOT import TCanvas, TH1D, TRandom, gRandom
 2
 3# キャンバスを作成
 4c = TCanvas("c", "Divided Canvas", 1200, 800)
 5
 6# キャンバスを2×3に分割
 7c.Divide(2, 3)
 8
 9# 5番目の領域に描画
10c.cd(5)

メソッドのシグネチャ

1// キャンバスを分割
2void Divide(Int_t nx = 1,
3            Int_t ny = 1,
4            Float_t xmargin = 0.01,
5            Float_t ymargin = 0.01,
6            Int_t color = 0);
7
8// 領域を選択
9TPad *cd(Int_t subpadnumber = 0);

パラメーターの説明

Divide()

nx - X方向の分割数

  • デフォルト値:1

  • 例:nx=2, ny=3の場合、2×3 = 6つの領域に分割

ny - Y方向の分割数

  • デフォルト値:1

xmargin - 領域間のX方向マージン

  • デフォルト値:0.01(1%)

  • 0.0~1.0の範囲で指定

ymargin - 領域間のY方向マージン

  • デフォルト値:0.01(1%)

  • 0.0~1.0の範囲で指定

color - 背景色

  • デフォルト値:0(白)

cd()

subpadnumber - 領域番号

  • 1から始まる番号で領域を指定

  • 0の場合はメインキャンバスを選択

  • 左上が1、右方向に増加

基本的な使い方

 1#include <TCanvas.h>
 2#include <TH1D.h>
 3#include <TRandom.h>
 4
 5TCanvas *c = new TCanvas("c", "Divided Canvas", 1200, 800);
 6
 7// キャンバスを2×2に分割
 8c->Divide(2, 2);
 9
10// 各領域に異なるヒストグラムを描画
11for (int i = 1; i <= 4; i++) {
12    c->cd(i);  // i番目の領域を選択
13    TH1D *h = new TH1D(Form("h%d", i), Form("Histogram %d", i), 100, -3, 3);
14    for (int j = 0; j < 10000; j++) {
15        h->Fill(gRandom->Gaus(0, 1));
16    }
17    h->Draw();
18}

マージンを調整したい

 1#include <TCanvas.h>
 2#include <TH1D.h>
 3
 4TCanvas *c = new TCanvas("c", "Canvas with Custom Margins", 1000, 800);
 5
 6// 2×3に分割、マージンを調整
 7c->Divide(2, 3, 0.05, 0.05);  // X、Yマージンを5%に設定
 8
 9for (int i = 1; i <= 6; i++) {
10    c->cd(i);
11    TH1D *h = new TH1D(Form("h%d", i), Form("Histo %d", i), 50, -3, 3);
12    h->FillRandom("gaus", 1000);
13    h->Draw();
14}

マージンを大きくすると領域同士の間隔が広がります。

領域のサイズが異なるグリッド

 1#include <TCanvas.h>
 2#include <TH1D.h>
 3
 4TCanvas *c = new TCanvas("c", "Uneven Division", 1200, 800);
 5
 6// 均等な2×2グリッドを作成
 7c->Divide(2, 2);
 8
 9// 領域1:メインプロット
10c->cd(1);
11TH1D *h1 = new TH1D("h1", "Main Plot", 100, -3, 3);
12h1->FillRandom("gaus", 5000);
13h1->Draw();
14
15// 領域2~4:補助プロット
16for (int i = 2; i <= 4; i++) {
17    c->cd(i);
18    TH1D *h = new TH1D(Form("h%d", i), Form("Sub %d", i), 50, -3, 3);
19    h->FillRandom("gaus", 1000);
20    h->Draw();
21}

領域を選択した後の操作

 1#include <TCanvas.h>
 2#include <TGraph.h>
 3
 4TCanvas *c = new TCanvas("c", "Canvas", 1000, 600);
 5c->Divide(1, 2);  // 1×2に分割
 6
 7// 上の領域
 8c->cd(1);
 9TGraph *g1 = new TGraph();
10for (int i = 0; i < 10; i++) {
11    g1->SetPoint(i, i, i * i);
12}
13g1->SetTitle("Upper Area");
14g1->Draw("APL");
15
16// 下の領域
17c->cd(2);
18TGraph *g2 = new TGraph();
19for (int i = 0; i < 10; i++) {
20    g2->SetPoint(i, i, sqrt(i));
21}
22g2->SetTitle("Lower Area");
23g2->Draw("APL");

メインキャンバスに戻したい

 1#include <TCanvas.h>
 2
 3TCanvas *c = new TCanvas("c", "Canvas", 800, 600);
 4c->Divide(2, 2);
 5
 6// 各領域に描画
 7for (int i = 1; i <= 4; i++) {
 8    c->cd(i);
 9    // ... 描画処理 ...
10}
11
12// メインキャンバスに戻す
13c->cd(0);
14// メインキャンバス上のタイトルなどを追加
15c->SetTitle("Main Title");

注意点

  • 領域番号は1から始まる - 0はメインキャンバスを示す

  • 左上から右方向に番号が増加 - 2×3の場合:

1 2
3 4
5 6
  • Divide()は複数回呼び出せない - すでに分割済みのキャンバスに再度Divide()を呼び出すと前の分割は上書きされる

  • マージンの合計が1.0を超えないようにする - 領域が重なる可能性がある

関連メソッド

  • TCanvas - キャンバスの基本

  • TCanvas::SaveAs - 分割されたキャンバスを保存

  • TPad - 領域(パッド)の詳細設定

参考資料