この記事では、gnuplot(グラフ作成ソフト)によって、実験データのアニメーションを作成する方法を紹介します。
- はじめに
- gnuplotによるgifアニメ作成の基本
- データファイルを利用したgifアニメの作成
- データファイルが連番ファイルの場合
- 連番gifファイルへ出力する場合
- 視点の回転
- その他のサンプルスクリプト置き場
- 参考資料
- おわりに
はじめに
gnuplotにはgifアニメを出力する機能があり、比較的簡単にアニメーションを作成することができます。gifアニメはPowerPointのスライドに張り付けると、スライドショーの時に自動的に再生されるので、作成したgifアニメは発表資料に使うことができます。
特に3次元データや時系列データの場合は、アニメーションで表現することで分かりやすくなると思います。
なお、この記事ではgnuplotの基本的な使い方は知っているものとして、説明します。
gnuplotによるgifアニメ作成の基本
gnuplotのgifアニメを出力する機能を利用しつつ、グラフを一コマずつプロットする事でgifアニメを作成できます。またグラフのプロットは、if
およびreread
関数を利用したループを用いることで簡単に行なうことができます。
以下にgifアニメを作成するスクリプトのサンプルを載せます。 両方のファイルを保存し、gpファイルの方をgnuplotから読み込む (gnuplotでload "gnuplot_sample1.gp"
)と、サンプルのgifアニメが出力されます。
[gnuplot_sample1.gp(クリックで表示)]
#------------------------------------------------------------------------------- # gnuplotの設定 #------------------------------------------------------------------------------- reset set nokey # 凡例の非表示 set xrange [-10:10] # x軸方向の範囲の設定 set yrange [-3:3] # y軸方向の範囲の設定 set term gif animate # 出力をgifアニメに設定 set output "sample1.gif" # 出力ファイル名の設定 #------------------------------------------------------------------------------- # 変数の設定 #------------------------------------------------------------------------------- n0 = 0 # ループ変数の初期値 n1 = 2*pi # ループ変数の最大値 dn = 2*pi/20 # ループ変数の増加間隔 #------------------------------------------------------------------------------- # ループの開始 #------------------------------------------------------------------------------- load "gnuplot_sample1.plt"
[gnuplot_sample1.plt(クリックで表示)]
#------------------------------------------------------------------------------- # ループ処理 #------------------------------------------------------------------------------- if(exist("n")==0 || n<0) n = n0 # ループ変数の初期化 #------------------------------------------------------------------------------- # プロット #------------------------------------------------------------------------------- plot sin(x-n), sin(x+n), sin(x-n)+sin(x+n) #------------------------------------------------------------------------------- # ループ処理 #------------------------------------------------------------------------------- n = n + dn # ループ変数の増加 if ( n < n1 ) reread # ループの評価 undefine n # ループ変数の削除
[gifアニメサンプル、定常波(クリックで表示)]
データファイルを利用したgifアニメの作成
ループごとに毎回データファイルを読み込むことによって、データファイルからアニメーションを作成する事ができます。読み込むデータファイルは、以下のようにデータを2行の空白によって塊に分けて記述します。このような形式のデータであれば、プロットする際に「index」コマンドによってプロットするデータの塊を選択する事ができます。
X Y X Y ... X Y X Y ...
以下にgifアニメを作成するファイルのサンプルを載せます。 また例として2次元の反射壁ランダムウォークの計算プログラムとgifアニメを載せます.
[gnuplot_sample2.gp(クリックで表示)]
#------------------------------------------------------------------------------- # gnuplotの設定 #------------------------------------------------------------------------------- reset set nokey # 凡例の非表示 set xrange [-50:50] # x軸方向の範囲の設定 set yrange [-50:50] # y軸方向の範囲の設定 set size square # 図を正方形にする set term gif animate # 出力をgifアニメに設定 set output "sample2.gif" # 出力ファイル名の設定 #------------------------------------------------------------------------------- # 変数の設定 #------------------------------------------------------------------------------- n0 = 1 # ループ変数の初期値 n1 = 99 # ループ変数の最大値 dn = 1 # ループ変数の増加間隔 #------------------------------------------------------------------------------- # ループの開始 #------------------------------------------------------------------------------- load "gnuplot_sample2.plt"
[gnuplot_sample2.plt(クリックで表示)]
# gnuplot_sample2.plt #------------------------------------------------------------------------------- # ループ処理 #------------------------------------------------------------------------------- if(exist("n")==0 || n<0) n = n0 # ループ変数の初期化 #------------------------------------------------------------------------------- # プロット #------------------------------------------------------------------------------- plot "sample_data.dat" index n using 1:2 with lines # n番目のデータのプロット #------------------------------------------------------------------------------- # ループ処理 #------------------------------------------------------------------------------- n = n + dn # ループ変数の増加 if ( n < n1 ) reread # ループの評価 undefine n # ループ変数の削除
[プログラムサンプル、ランダムウォーク(クリックで表示)]
// // ランダムウォークのデータを出力する // #include <stdio.h> #include <stdlib.h> #include <time.h> #define n 50000 //最大繰り返し回数 int main() { int i, j; int random_num; FILE *output; char str[100]; double x[n],y[n]; output = fopen("sample_data.dat","w"); srand((unsigned) time(NULL)); x[0] = 0.0; y[0] = 0.0; for( i = 1; i < n; i++) { x[i] = x[i-1]; y[i] = y[i-1]; //乱数の数字の範囲によって4つの方向のどちらかへ移動 random_num = rand()%4; switch(random_num){ case 0: x[i] = x[i-1] - 1.0; break; case 1: x[i] = x[i-1] + 1.0; break; case 2: y[i] = y[i-1] - 1.0; break; case 3: y[i] = y[i-1] + 1.0; break; } // 反射壁 if( x[i-1] == 40 ) { x[i] = 39; y[i] = y[i-1]; } else if( x[i-1] == -40 ) { x[i] = -39; y[i] = y[i-1]; } else if( y[i-1] == 40 ) { x[i] = x[i-1]; y[i] = 39; } else if( y[i-1] == -40 ) { x[i] = x[i-1]; y[i] = -39; } // 500回ごとにファイルへ出力 if( i%500 == 0) { for(j = 0; j <= i; j++) { fprintf(output,"%f %f\n",x[j],y[j]); } // 2行空白(gnuplotでの解析用) fprintf(output,"\n\n"); } } fclose(output); return 0; }
[gifアニメサンプル、ランダムウォーク(クリックで表示)]
データファイルが連番ファイルの場合
読み込むデータを前述したように2行の空白で分ける代わりに、別ファイルに分けた連番ファイルを利用する場合は、以下のサンプルのように、毎ループごとにその連番ファイルを読み込みプロットします。
[gnuplot_sample3.gp(クリックで表示)]
#------------------------------------------------------------------------------- # gnuplotの設定 #------------------------------------------------------------------------------- reset set nokey # 凡例の非表示 set xrange [-50:50] # x軸方向の範囲の設定 set yrange [-50:50] # y軸方向の範囲の設定 set size square # 図を正方形にする set term gif animate # 出力をgifアニメに設定 set output "sample3.gif" # 出力ファイル名の設定 #------------------------------------------------------------------------------- # 変数の設定 #------------------------------------------------------------------------------- n0 = 1 # ループ変数の初期値 n1 = 99 # ループ変数の最大値 dn = 1 # ループ変数の増加間隔 #------------------------------------------------------------------------------- # ループの開始 #------------------------------------------------------------------------------- load "gnuplot_sample3.plt"
[gnuplot_sample3.plt(クリックで表示)]
# gnuplot_sample3.plt #------------------------------------------------------------------------------- # ループ処理 #------------------------------------------------------------------------------- if(exist("n")==0 || n<0) n = n0 # ループ変数の初期化 #------------------------------------------------------------------------------- # プロット #------------------------------------------------------------------------------- filename = sprintf("sample_data_%03d.dat", n) # n番目のデータファイルの名前の生成 plot filename using 1:2 with lines # n番目のデータのプロット #------------------------------------------------------------------------------- # ループ処理 #------------------------------------------------------------------------------- n = n + dn # ループ変数の増加 if ( n < n1 ) reread # ループの評価 undefine n # ループ変数の削除
連番gifファイルへ出力する場合
前述した方法ではgnuplotのgifアニメ作成機能を用いていましたが、gnuplotでgifファイルを一枚ずつ出力し、そのgifファイルから別のソフトを用いてアニメーションを作成する事もできます。
以下に連番gifファイルを出力するスクリプトのサンプルを載せます。
[gnuplot_sample4.gp(クリックで表示)]
#------------------------------------------------------------------------------- # gnuplotの設定 #------------------------------------------------------------------------------- reset set nokey # 凡例の非表示 set xrange [-50:50] # x軸方向の範囲の設定 set yrange [-50:50] # y軸方向の範囲の設定 set size square # 図を正方形にする set term gif # 出力をgifに設定 #------------------------------------------------------------------------------- # 変数の設定 #------------------------------------------------------------------------------- n0 = 1 # ループ変数の初期値 n1 = 99 # ループ変数の最大値 dn = 1 # ループ変数の増加間隔 #------------------------------------------------------------------------------- # ループの開始 #------------------------------------------------------------------------------- load "gnuplot_sample4.plt"
[gnuplot_sample4.plt(クリックで表示)]
# gnuplot_sample4.plt #------------------------------------------------------------------------------- # ループ処理 #------------------------------------------------------------------------------- if(exist("n")==0 || n<0) n = n0 # ループ変数の初期化 #------------------------------------------------------------------------------- # プロット #------------------------------------------------------------------------------- filename = sprintf("sample_gif_%03d.gif", n) # n番目の出力ファイルの名前の生成 set output filename # 出力ファイル名の設定 plot "sample_data.dat" index n using 1:2 with lines # n番目のデータのプロット #------------------------------------------------------------------------------- # ループ処理 #------------------------------------------------------------------------------- n = n + dn # ループ変数の増加 if ( n < n1 ) reread # ループの評価 undefine n # ループ変数の削除
視点の回転
視点を回転するアニメーションを作成すれば、3次元データなどは見やすくなると思います。ループごとに視点を少しずつずらすことによって、視点を回転させるアニメーションを作成する事ができます。
以下に視点を回転させるgifアニメを作成するスクリプトのサンプルを載せます。
[gnuplot_sample5.gp(クリックで表示)]
#------------------------------------------------------------------------------- # gnuplotの設定 #------------------------------------------------------------------------------- reset set nokey # 凡例の非表示 set xrange [-5:5] # x軸方向の範囲の設定 set yrange [-5:5] # y軸方向の範囲の設定 set ticslevel 0 # z軸の原点をxy平面に合せる set isosamples 20, 20 # メッシュの間隔の設定 set hidden3d # 隠線処理の設定 set term gif animate # 出力をgifアニメに設定 set output "sample5.gif" # 出力ファイル名の設定 #------------------------------------------------------------------------------- # 変数の設定 #------------------------------------------------------------------------------- n0 = 0 # ループ変数の初期値 n1 = 89 # ループ変数の最大値 dn = 1 # ループ変数の増加間隔 #------------------------------------------------------------------------------- # ループの開始 #------------------------------------------------------------------------------- load "gnuplot_sample5.plt"
[gnuplot_sample5.plt(クリックで表示)]
#------------------------------------------------------------------------------- # ループ処理 #------------------------------------------------------------------------------- if(exist("n")==0 || n<0) n = n0 # ループ変数の初期化 #------------------------------------------------------------------------------- # 視線の変更 #------------------------------------------------------------------------------- set view 60, n; # 視点の変更 #------------------------------------------------------------------------------- # プロット #------------------------------------------------------------------------------- splot (x**2)*(y**2) #------------------------------------------------------------------------------- # ループ処理 #------------------------------------------------------------------------------- n = n + dn # ループ変数の増加 if ( n < n1 ) reread # ループの評価 undefine n # ループ変数の削除
[gifアニメサンプル、視点の回転(クリックで表示)]
その他のサンプルスクリプト置き場
三次元正葉曲線の軌跡
このページの冒頭のアニメーションです.
[gnuplot_folium.gp(クリックで表示)]
#------------------------------------------------------------------------------- # gnuplotの設定 #------------------------------------------------------------------------------- reset set nokey # 凡例の非表示 set xrange [-1.2:1.2] # x軸方向の範囲の設定 set yrange [-1.2:1.2] # y軸方向の範囲の設定 set zrange [-1.2:1.2] # z軸方向の範囲の設定 set ticslevel 0 # z軸の原点をxy平面に合せる set grid xtics ytics ztics # グリッドの表示 set border 127+256+512 # 軸の表示 set parametric # 媒介変数表示の設定 set angles degrees # 角度の単位を[deg]に変更 set style line 1 linewidth 3 # 線を太くする set term gif animate # 出力をgifアニメに設定 set output "folium.gif" # 出力ファイル名設定 #------------------------------------------------------------------------------- # 変数の設定 #------------------------------------------------------------------------------- n0 = 0 # ループ変数の初期値 n1 = 360 # ループ変数の最大値 dn = 4 # ループ変数の増加間隔 delay = 1 # 表示する残像の遅れ a = 5 # 正葉曲線の係数 #------------------------------------------------------------------------------- # 関数の定義 #------------------------------------------------------------------------------- fx(t) = cos(a*t)*cos(2*t) fy(t) = cos(a*t)*sin(2*t) fz(t) = cos(a*t) #------------------------------------------------------------------------------- # ループの開始 #------------------------------------------------------------------------------- load "gnuplot_folium.plt"
[gnuplot_folium.plt(クリックで表示)]
#------------------------------------------------------------------------------- # ループ処理 #------------------------------------------------------------------------------- if(exist("n")==0 || n<0) n = n0 # ループ変数の初期化 #------------------------------------------------------------------------------- # プロット #------------------------------------------------------------------------------- # 3次元の正葉曲線と残像のプロット splot fx(n),fy(n),fz(n) linestyle 1,\ fx(n+delay), fy(n+delay),fz(n+delay) linestyle 1,\ fx(n+2*delay), fy(n+2*delay),fz(n+2*delay) linestyle 1,\ fx(n+3*delay), fy(n+3*delay),fz(n+3*delay) linestyle 1,\ fx(n+4*delay), fy(n+4*delay),fz(n+4*delay) linestyle 1,\ fx(n+5*delay), fy(n+5*delay),fz(n+5*delay) linestyle 1,\ fx(n+6*delay), fy(n+6*delay),fz(n+6*delay) linestyle 1,\ fx(n+7*delay), fy(n+7*delay),fz(n+7*delay) linestyle 1,\ fx(n+8*delay), fy(n+8*delay),fz(n+8*delay) linestyle 1,\ fx(n+9*delay), fy(n+9*delay),fz(n+9*delay) linestyle 1 #------------------------------------------------------------------------------- # ループ処理 #------------------------------------------------------------------------------- n = n + dn # ループ変数の増加 if ( n < n1 ) reread # ループの評価 undefine n # ループ変数の削除
球の回転
アイキャッチ画像の、球の回転アニメーションです。
[gnuplot_sphere.gp(クリックで表示)]
#------------------------------------------------------------------------------- # gnuplotの設定 #------------------------------------------------------------------------------- reset set nokey # 凡例の非表示 set noxtics # 軸の非表示 set noytics set noztics set ticslevel 0 # z軸の原点をxy平面に合せる set size 0.7,1.0 # サイズの設定 set border 0 # 軸の非表示 set parametric # 媒介変数表示の設定 set urange [0:360] # 媒介変数uの範囲の設定 set vrange [-90:90] # 媒介変数vの範囲の設定 set angle degree # 角度の単位を[deg]に変更 set isosample 18,18 # メッシュの間隔の設定 set terminal gif animate # 出力をgifアニメに設定 set output "sphere.gif" # 出力ファイル名設定 #------------------------------------------------------------------------------- # 変数の設定 #------------------------------------------------------------------------------- n0 = 0 # ループ変数の初期値 n1 = 20 # ループ変数の最大値 dn = 1 # ループ変数の増加間隔 #------------------------------------------------------------------------------- # ループの開始 #------------------------------------------------------------------------------- load "gnuplot_sphere.plt"
[gnuplot_sphere.plt(クリックで表示)]
#------------------------------------------------------------------------------- # ループ処理 #------------------------------------------------------------------------------- if(exist("n")==0 || n<0) n = n0 # ループ変数の初期化 #------------------------------------------------------------------------------- # 視線の変更 #------------------------------------------------------------------------------- set view 60, n; # 視線の変更 #------------------------------------------------------------------------------- # プロット #------------------------------------------------------------------------------- # 球のプロット splot cos(u)*cos(v),sin(u)*cos(v),sin(v) #------------------------------------------------------------------------------- # ループ処理 #------------------------------------------------------------------------------- n = n + dn # ループ変数の増加 if ( n < n1 ) reread # ループの評価 undefine n # ループ変数の削除
参考資料
- http://t16web.lanl.gov/Kawano/gnuplot/misc1.html
- ※現在リンクが切れていますが記載しておきます。移転先が見つかったら修正します。
- http://cosmo.phys.hirosaki-u.ac.jp/wiki.cgi/gnuplot?page=波動:簡易アニメーション
- ※現在リンクが切れていますが記載しておきます。移転先が見つかったら修正します。
- gnuplotでアニメーション直接 gif アニメーションを出力する
- ランダムウォークの数値計算例(C言語)
- gnuplotスクリプトのループ - 米澤進吾 ホームページ
おわりに
もっといい方法があれば教えてください。