[Windows] C言語でgnuplotを動かしてアニメーションを作る

このページはそのうち完成させます。上のgifはパワーポイントに貼ってプレゼンでも使えます。


点が動くプログラム


 gnuplotでアニメーションをする方法は色々あるけれど、上の図のように沢山の点が何回も動く場合は

1. 各点の位置情報をテキストファイルに保存。
2. ファイルをgnuplotで読み込んで一気に表示。
 を繰り返すのが早い。

#include <stdio.h>
#include <windows.h>	// for Sleep
#include <winbase.h>

#define GNUPLOT_PATH "C:/gnuplot/bin/pgnuplot.exe"	// pgnuplot.exeもしくはgnuplot.exeの場所

void main(){
	FILE *gp, *fp;
	int i,nod;
	// 初期配置
	double X[9][2] = {{0.0,0.0},{0.1,0.0},{0.2,0.0},
			{0.0,0.1},{0.1,0.1},{0.2,0.1},
			{0.0,0.2},{0.1,0.2},{0.2,0.2}};

	// Animation settings
	// gnuplotを動かすためのコマンド
	if ((gp = _popen(GNUPLOT_PATH, "w")) == NULL) {
		printf("gnuplot open error!!\n");
		exit(EXIT_FAILURE);	// エラーの場合は通常、異常終了する
	}

	// Gnuplot操作
	fprintf(gp, "set size square\n");		// figureを正方形に
	fprintf(gp, "set xrange [%f:%f]\n",0.0,3.0); // 範囲の指定
	fprintf(gp, "set yrange [%f:%f]\n",0.0,3.0);
	fprintf(gp, "unset key\n");		// 凡例を表示しない

	// 点の位置を動かす
	for(i=0;i<30;i++){
		fp = fopen("move_point.dat", "w");	// "上書き"モードでファイルを開く。
		fprintf(gp, "set title 't = %d'\n",i); // タイトルを設定
		for(nod=0;nod<9;nod++){			// 9個の点の位置をファイルに保存
			fprintf(fp,"%f %f\n",X[nod][0],X[nod][1]);	// 点nodの位置をファイルに書き込み
			X[nod][0] += 0.1; X[nod][1] += 0.1;		// 点nodの位置を0.1ずつずらす
		}
		fprintf(gp,"plot 'move_point.dat' w p pt 7 ps 0.5\n");	// gnuplotで点を描く
		fclose(fp);	// 位置を書いているファイルを閉じる
		fflush(gp);	// バッファに格納されているデータを吐き出す(必須)
		Sleep(100);	// なくてもよい。
	}
	system("pause");
	
	fprintf(gp, "exit\n"); // gnuplotの終了
	fflush(gp); // バッファに格納されているデータを吐き出す(必須)
	_pclose(gp);
}

 上の解説。
 'move_point.dat'というファイルに各点の位置を書き換えながら保存していく。  初期配置の場合、'move_point.dat'の中身は  

0.0 0.0
0.1 0.0
0.2 0.0
0.0 0.1
0.1 0.1
0.2 0.1
0.0 0.2
0.1 0.2
0.2 0.2
 となっている。点の位置(Xの値)を動かしたら、このファイルを書き換える。追記ではないことに注意。
 つまり、'move_point.dat'の中身は、必ず9行x2列(点の数x次元数)となっている。
  これを、gnuplotで読み込んで描かせる。コマンドは
plot 'move_point.dat' w p pt 7 ps 0.5  # pointsizeは50%
 となる。
 これを繰り返すことで、アニメーションになる。

アニメーションをgifファイルで保存

 アニメーションをgifファイルアニメーションにするには、

  1. 各状態の画像をgifファイルで保存。30ステップ分なら30枚。
  2. これらのgifファイルをgiamdでつなげて一つのgifアニメーションにする。
 という手順をふむ。

 具体的には、上のアニメーションのプログラムの、Sleep(100)の一つ上の行に、

  fprintf(gp,"name='move%02d'\n load 'savegif.gp'\n",i+1);
 を追記する。savegif.gpの中身は、
 if (exists("name")){ 
  filename = sprintf("%s.gif",name);
  set terminal gif enhanced # terminalをgifに変更
  set output filename       # ファイル名で保存場所を指定可能
  pause 1                   # 1秒待つ。PCが高速の場合は処理を待つために必要。
  replot                    # 必要
  set output                # 必要。これで、先ほど作ったgifがcloseされる。
  set terminal wxt          # ターミナルをもとに戻す(wxtでなくても良い)
 }else{
  pause -1 "nameを指定して下さい。name='ファイル名'"
}
 とし、適当なフォルダに置いておく。上のコマンドの場合は、.cがあるフォルダと同じ場所。

Back