C/C++からgnuplotを使うと題しているが、そもそもgnuplotとは何かについて簡単に紹介する。gnuplot公式サイトにあるとおり、"Gnuplot is a portable command-line driven graphing utility" つまり、コマンドラインベースのグラフ描画ツールである。クロスプラットフォームで、Linuxだけではなく、Windows、Mac用のバイナリも用意されている。
gnuplot自体の詳細な使い方は、公式ドキュメントや下に挙げたWebサイトを参照してほしい。ちなみに私が卒論や修論を書いたときには「使いこなすgnuplot」と「LaTeX2e 美文書作成入門
」を見ながら書いたが、「使いこなすgnuplot
」の在庫がなくなってきているようだ。
ここからが本題で、C/C++で書いたプログラムの結果をグラフにする場合の作業を考えると、一般に次のようになる。
- プログラムから結果をCSVなどでファイル出力する。
- 出力したCSVファイルをgnuplotに入力しグラフを作成する。
作成するグラフが1つや2つのときはちょっとした手間くらいですむが、いろいろな条件で多数のグラフを作成するとなると、なんとかして自動化をしたくなる。スクリプト化してしまうというのも一つの方法で、私もスクリプト化してグラフの画像ファイルを自動生成していた。じゃあスクリプトでとなると話が終わってしまうので、もう一つの方法として、プログラム内からgnuplotを呼び出してしまうという方法がある。
「gnuplot C」や「gnuplot C++」をキーワードとして検索すると、大きく2つの方法があるようだった。
- system()関数をつかってシェルやコマンドプロンプトにコマンドを送る
- パイプをつかってgnuplotのプロセスにコマンドを送る
system関数を送る方は事前にスクリプトでも用意しておき、それを呼び出す文字列をsystem関数の引数とすればいい。ただ、事前にスクリプトを用意しておくことを考えると、2のパイプを使って操作した方が汎用性が高く、使い勝手がよさそうに感じた。
まずは大まかな流れを以下に示す。
- popen (Windowsの場合は_popen)関数でgnuplotのプロセスとの間にパイプを開く。
- 1で作成したパイプにfprintfなどでgnuplotのコマンドを入力する。
- fflushを実行し、2でバッファに溜まっているコマンドをgnuplotのプロセスに書き込む。
- pclose (Windowsの場合は_pclose)関数でgnuplotのプロセスとの間のパイプを閉じる。
実際のコードは次の通り
#include <cstdio> #include <cstdlib> using namespace std; int main(int argc, char* argv[], char* envp[]) { FILE* gnuplot = _popen("pgnuplot", "w") //Linuxではpopen fprintf(gnuplot, "plot sin(x)\n"); //y=sin(x)を描画する fflush(gnuplot); //バッファを書き出す return EXIT_SUCCESS; }
実行すると次のようなグラフが表示される。
このコードは「gnuplot をC/C++から使う方法」の情報を参照した。サイト内にgnuplotクラスを作成したという記述はあったが、ダウンロードはできなかった。また、「凹みTips」では、この方法でgnuplotクラスを作成していた。
また、stdioではなくiostreamを使えないかと調べたところ、「Boost C++ Libraries」のiostreamを使用すれば、うまくいきそうだという情報もあったが、それはまた今度で。
<gnuplot参考サイト>
コメント