0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

CERN ROOT (C++) グラフ作成 (1) sin,cosのグラフの重ね表示

Last updated at Posted at 2024-10-26

概要

通常グラフを作成するときはEXCEL、pythonのmatplotlibseabornなど、あるいはgnuplot使うことが多くC++でのグラフ作成はあまり見られません。そこで、CERN ROOTでのグラフ作成を紹介したいと思います。
CERN ROOTはC++のインタプリタでも、C++のコンパイラを用いてバイナリーでも動かすことができるので両方を紹介します。さらにJupyter Notebookも紹介します。
通常、グラフはjpeg,png,gifなどの画像ファイルを作成することが多いと思いますが、CERN ROOTは専用GUI上にグラフを表示し、グラフに対してインタラクティブにいくつかの操作をすることができます。当然、画像ファイルとしても保存することが可能です。

実行環境

sw_vers
ProductName:		macOS
ProductVersion:		14.6.1
BuildVersion:		23G93

root --version
ROOT Version: 6.32.06
Built for macosxarm64 on Sep 21 2024, 18:21:53
From tags/6-32-06@6-32-06

g++ --version
Apple clang version 15.0.0 (clang-1500.3.9.4)
Target: arm64-apple-darwin23.6.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

REPLでソースファイルを実行するためのコマンドとプログラムの作り方

ソースファイルの拡張子に特に決まりはありませんが、ROOTで使われているのは.Cです。個人的にはインタプリタ用のソースを.Cでコンパイルしてバイナリを作るためのソースを.ccとしています。

ソースファイルを読み込み、ファイル名を同じ関数名を実行するコマンド

root [0] .x ファイル名
root [1] .x ファイル名(引数1, ...)
sample01.C
void sample01() {
    printf("sample01\n");
}

sample01.Cを実行する

root [1] .x sample01.C
sample01
root [2]
sample02.C
void sample02_sub() {
    printf("sample02_sub\n");
}
void sample02(int n, const char * const c) {
    sample02_sub();
    printf("n=%d c=%s\n", n,  c);
}

sample02.Cを実行する

root [0] .x sample02.C(123,"abcd")
sample02_sub
n=123 c=abcd
root [1] char c[]="xyz";
root [2] sample02(456,c);
sample02_sub
n=456 c=xyz
root [3]

2番目の引数に文字列を直接指定するのでconst char* constとしないと警告がでる。関数sample02REPL上で定義済みになるので、何度でも関数sample02を呼び出すことができる。

ソースの読み込みをするコマンド

root [0] .L ファイル名

ソースを読み込むが関数は実行されない。しかし関数外、つまりグローバルに記述されているコードは実行される。

root [0] .L sample02.C
root [1] sample02(789,"uiop");
sample02_sub
n=789 c=uiop
root [2]

当然ですが、ファイル名と同じ関数が存在しなくても大丈夫です。関数が1つも含まれていなくてもOKです。

sample03.C
int sum = 0;
for (int i = 1; i <= 1000; i++)
    sum += i;
printf("sum=%d\n", sum);

sample03.Cの読み込み

root [0] .L sample03.C
sum=500500
root [1] 

REPLでプログラムソースを実行させてsin,cosのグラフの重ね表示

sin関数とcos関数のグラフを重ねて表示させる。ここでは画像ファイルの書き出しではなくGUI上にグラフを表示させます。
画像ファイルの書き出しはもちろんプログラムで可能ですし、GUIのメニューから画像ファイルの書き出しも可能です。

sincos.C
void sincos() {
    constexpr int n = 100;
    float x[n], ys[n], yc[n];
    for(int i=0; i < n; i++){
        x[i] = 0.04 * i;
        ys[i] = TMath::Sin(x[i]*4);
        yc[i] = TMath::Cos(x[i]*4);
    }
    auto gr = new TGraph(n, x, ys);
    gr->SetMarkerStyle(20);
    gr->SetMarkerColor(2);
    gr->Draw("apc");
    auto gr2 = new TGraph(n, x, yc);
    gr2->SetMarkerColor(4);
    gr2->SetMarkerStyle(40);
    gr2->Draw("pc");
}

sincos.Cを実行する

root [0] .x sincos.C
Info in <TCanvas::MakeDefCanvas>:  created default TCanvas with name c1
root [1]

2024-10-26 16.16.52.png

ソースの解説

注意点

grgr2deleteしない。deleteすると描画したグラフも消去される。

グラフの描画にはTCanvasのオブジェクトが必要であるが、自動的に生成されるのでプログラムで生成する必要はない

Drawオプション
Option Description
"A" Produce a new plot with Axis around the graph
"I" Combine with option 'A' it draws invisible axis
"L" A simple polyline is drawn
"F" A fill area is drawn ('CF' draw a smoothed fill area)
"C" A smooth Curve is drawn
"*" A Star is plotted at each point
"P" The current marker is plotted at each point
"B" A Bar chart is drawn
"1" When a graph is drawn as a bar chart, this option makes the bars start from the bottom of the pad. By default they start at 0.
"X+" The X-axis is drawn on the top side of the plot.
"Y+" The Y-axis is drawn on the right side of the plot.
"PFC" Palette Fill Color: graph's fill color is taken in the current palette.
"PLC" Palette Line Color: graph's line color is taken in the current palette.
"PMC" Palette Marker Color: graph's marker color is taken in the current palette.
"RX" Reverse the X axis.
"RY" Reverse the Y axis.

画像ファイルとしての書き出し

メニューの[File]->[Save] or [Save As]を選べばps,eps,pdf,tex,gif,png,Cプログラム,rootファイルの書き出しが可能です。さらに、メニューの[View]->[Editor]でグラフのマーカーの種類や色を変えることが可能です。

g++でコンパイルしてバイナリを作成して実行

コンパイルするためインタプリタとして実行するのとは異なり、ヘッダーファイルのincludeなど完全なC++プログラムを書かなければならない。
上記のsincos.Cの完全なc++ソースを以下の示します。拡張子は.ccで作成しました。

sincos.cc
#include <TApplication.h>
#include <TCanvas.h>
#include <TGraph.h>
#include <TMath.h>
#include <TRootCanvas.h>

int main(int argc, char* argv[]) {
    TApplication app("app", &argc, argv);
    TCanvas c1("c1");
    constexpr int n = 100;
    float x[n], ys[n], yc[n];
    for(int i=0; i < n; i++){
        x[i] = 0.04 * i;
        ys[i] = TMath::Sin(x[i]*4);
        yc[i] = TMath::Cos(x[i]*4);
    }
    TGraph gr(n, x, ys);
    gr.SetMarkerStyle(20);
    gr.SetMarkerColor(2);
    gr.Draw("apc");
    TGraph gr2(n, x, yc);
    gr2.SetMarkerColor(4);
    gr2.SetMarkerStyle(40);
    gr2.Draw("pc");
    c1.Update();

    TRootCanvas *rc = (TRootCanvas *)c1.GetCanvasImp();
    rc->Connect("CloseWindow()", "TApplication", gApplication, "Terminate()");
    
    app.Run();
    return 0;
}

sincos.ccをg++でコンパイルして実行する

g++ sincos.cc -o  sincos `root-config --cflags --libs`

./sincos

root-configがCERN ROOTのincludeやリンクライブラリーの指定をしてくれます。
GUIはREPLのときと同じです。よってGUIのスクショは省略します。

PyROOTによるPythonでの同じグラフ表示

CERN ROOTはPythonのライブラリも提供していて追加インストールなしで使えます。
ただし、Pythonを動かく前に以下のスクリプトを実行してください。これはPYTHONPATHにCERN ROOTのbinを設定する必要があるためです。

source thisroot.sh

thisroot.???はWindows用も含めCERN ROOTのbinディレクトリに含まれています。

sincos.py
import ROOT as RT
from array import array

c1 = RT.TCanvas("c1")
n = 100
x = array('f',[0]*n)
ys = array('f',[0]*n)
yc = array('f',[0]*n)
for i in range(n):
    x[i] = 0.04 * i;
    ys[i] = RT.TMath.Sin(x[i]*4);
    yc[i] = RT.TMath.Cos(x[i]*4);
gr = RT.TGraph(n, x, ys)
gr.SetMarkerStyle(20)
gr.SetMarkerColor(2)
gr.Draw("apc");
gr2 = RT.TGraph(n, x, yc)
gr2.SetMarkerColor(4)
gr2.SetMarkerStyle(40)
gr2.Draw("pc")
c1.Update()

rc = c1.GetCanvasImp()
rc.Connect("CloseWindow()", "TApplication", RT.gApplication, "Terminate()");

RT.gApplication.Run()

配列はarray.arrayを使う必要があるようです。ちなみに第1引数の'f'は配列のデータがfloatタイプであることを表しています。

sincos.pyの実行

python3 sincos.py

GUIはREPLのときと同じです。よってGUIのスクショは省略します。

Jupyter Notebookでグラフを書く

Jupyter Notebookの起動

root --notebook

2024-10-26 22.02.28.png
2024-10-26 22.00.41.png

当然Pythonを選んでもpyROOTを使えばJupyter Notebook上にグラフを表示できます。

2024-10-26 22.18.53.png

終わりに

グラフのクラスはTGraph以外にもたくさんありすが、日本語の情報が少ないのでなかなか大変です。
グラフ作成にPythonやEXCELばかり使っていますが、C/C++を忘れないためにもC++でグラフを作るのも良いと思います。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?