【ROOT】TGraphクラスでグラフを描画する

今回はROOTでグラフを描画する方法を紹介します。 ====

はじめに

ROOTは基本的にC++Pythonの記法を利用して書くことができます。

C++で利用する場合にはC++ソースコードC++で書いたROOTのソースコードを区別しておく必要があります。


私の場合

という拡張子にしています。


また、C++ではメイン関数を必要とします。
しかし、ROOTの場合必要ありません。

TGraph

以前、メルセンヌツイスターで乱数生成し、ランダムウォークを描画しました。
dandy-tech.hatenablog.jp

これもTGraphクラスを用いて描画しています。
更にフィッティングなど強力な機能が利用できます。

クラスの定義

まずTGraphでplotする際に利用するクラスがあります

TCanvas *c1 = new TCanvas("c1", "", 0, 0, 800, 600);  
TGraph *g1 = new TGraph(i, x, y);
TF1 *func1 = new TF1("func1", "1/[0]*(x-[1])", 0, 100);
  • TCanvas

TCanvas はデータ点のプロットだけでなく、その軸ラベルも含めたグラフ全体に当たります。

  • TGraph

TGraph は今回のプロットを作るためのクラスで今回の主役です。

  • TF1

TF1 はプロットした点に対してフィッティング関数を自分で定義してFitできます。
ROOTには内部関数として指数関数や線形関数が実装されているため、TF1は必ずしも必要ではありません。

コード内で計算して描画する

具体的にどんなコードを書けばいいかを見てみたほうがわかりやすいと思います。

Fourier変換で馴染みのあるsinc関数をTGraphでプロットしてみます。

ソースコードC++

以下がそのコードです。

{
  const int n = 1000;
  double x[n], y[n];
  int i;
  
  for (i=0; i<n; ++i) {
      x[i] = 0.1*(i+1);
      y[i] = sin(x[i])/x[i];
  }
  
  TCanvas *c1 = new TCanvas("c1", "", 0, 0, 800, 600);  
  TGraph *g1 = new TGraph(n, x, y);

  c1 -> SetGrid(1);
  c1 -> Draw();    
  c1 -> Update();    
  
  g1 -> GetXaxis() -> SetTitle("x");  
  g1 -> GetYaxis() -> SetTitle("y"); 
  g1 -> SetMarkerStyle(4); 
  g1 -> SetMarkerColor(4);  
  g1 -> SetMarkerSize(0.5);   
  g1 -> Draw("AP");
  
  
  c1 -> Print(".png");   
  c1 -> Print(".pdf"); 

  return 0;
}

このソースコードをrootで実行します。

$ root filename.C

次のようなグラフが出力されます。

f:id:DanDy:20190706170910p:plain
sinc関数をプロット。

 

dataファイル、textファイルを読み込み描画する

ここはC++の作法と同じです。

入力データの中身は2列であること。
2列のデータをそれぞれx, yの配列に詰めていきます。

const int n=10000;  //ifstreamの入力データ数に依存
int i=0;
double x[n], y[n];

ifstream data(".dat");  
while(!data.eof()){
	data >> x[i] >> y[i];
	i++;
}
data.close();
ソースコードC++

では実際にコードを記述します。

{
const int n=10000;  //ifstreamの入力データ数に依存
int i=0;
double x[n], y[n];

ifstream data(".dat");  //input data
while(!data.eof()){
	data >> x[i] >> y[i];
	i++;
}
data.close();

TCanvas *c1 = new TCanvas("c1", "", 0, 0, 800, 600);  
TGraph *g1 = new TGraph(n, x, y);
//TF1 *func1 = new TF1("func1", "1/[0]*(x-[1])", 0, 100);

//func1 -> SetParameters(10, 10);  //set parameter[0],[1]

c1 -> SetGrid(1);   //gridを表示する
c1 -> Draw();    
c1 -> Update();    

g1 -> Draw("AP");   //Draw option
g1 -> GetXaxis() -> SetTitle("x");             
g1 -> GetXaxis() -> SetRangeUser(0., 1100.);  
g1 -> GetYaxis() -> SetTitle("y");            
g1 -> GetYaxis() -> SetRangeUser(-200, 200.);  
g1 -> SetTitle("title");
//g1 -> SetMarkerStyle(4); 
//g1 -> SetMarkerColor(4);  
//g1 -> SetMarkerSize(1);   
//g1 -> Fit("func1", "", "", 0, 100);

c1 -> Print(".png");  
c1 -> Print(".pdf");   

//gStyle -> SetOptFit();    

return 0;
}


以前記事にしたランダムウォークはこれで描画しました。
f:id:DanDy:20190629221834p:plain

 

ソースコード:Python3

jupyter notebookでの紹介になりますが、Python3では次のように記述します。

gist819145cb5ab3199d5b24f298464c310e



 

終わりに

TGraphを使用すると、プロットを作ることができます。
しかし、今回紹介したTGraphではError barが付きません。

でも安心してください。TGraphErrorsというError barが付けられるクラスがあるので問題ありません。
利用方法も変数が2個増えるだけです。


TGraphErrorsについてはまた記事にしますのでお待ちください。

おしまい。