Last update: 2024/12/15
gnuplotがインストールされてPATHが通っていること。gnuplotのインストールについてはこちらを参照。
前回はc++でgnuplotを操作して画像出力したが、サンプル数が多い数値解析の場合はデータの出力と可視化を分けたほうが何かと都合がよいかと思う。今回はまずc++でデータをtxtファイルとして出力して、それをコマンドライン上でgnuplotに与えて画像データを出力させてみる。
txtファイルで保存するデータだが、以前作成したモンテカルロ法のc++コードに、サンプルの座標をtxtファイルに書き出す処理を追加した。赤文字の部分が今回追加した内容である。
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <fstream>
int main(int argc, char *argv[]) {
int n = std::stoi(argv[1]);
double square = 0;
double circle = 0;
std::random_device seed;
std::mt19937 engine(seed());
std::uniform_real_distribution<> dist(0.0, 1.0);
std::ofstream outputfile("pi_xy_out.txt");
outputfile << "#pi x,y" << std::endl;
for(int i = 0; i < n; i++){
double x = dist(engine);
double y = dist(engine);
square += 1;
if(x*x + y*y <= 1) {
circle += 1;
}
// output for gnuplot
outputfile << x << ' ' << y << std::endl;
}
double pi = (circle / square) * 4;
std::cout << "pi:" << pi << std::endl;
outputfile.close();
return 0;
}
このコードをg++でコンパイルして実行したところ、pi_xy_out.txtというテキストファイルに座標情報が保存できた。
gnuplotでtxtファイルのデータをプロットするにあたり、以下の内容のシェルスクリプトを作成した。pi_xy_out.txtのデータを点としてプロットするのと同時に、半径0.5の円を描写させている。
#!/bin/bash
echo "monte carlo x,y plot"
gnuplot << EOF
set terminal pngcairo
set output "pi_montecarlo.png"
set zeroaxis
set size square
unset key
set parametric
plot [0:2*pi] 0.5*(cos(t)+1), 0.5*(sin(t)+1) with lines title 'Circle', "./pi_xy_out.txt" with points title 'Points'
exit
EOF
pi_xy_out.txtと同じディレクトリで上記のシェルスクリプトを置き、実行したところpi_montecarlo.pngという名前でpngファイルを保存できた。なお、set terminal pngcairoの部分はset terminal pngとしてもpngファイルを出力できるが、pngcairoの方がグラフの描画が改善されている。
以下が実際に表示した画像。pi_xy_out.txtに書かれた各サンプルの座標をplotできている。
C++でテキストに書き出す方法 #fstream - Qiita
gnuplot によるグラフ作成 - 弘前大学 Home Sweet Home
Copyright (c) 2024 kd