gnuplotとアニメーション

gnuplot上の様々なアニメーションを作ります。
dofor構文を使うのでgnuplot ver4.6以降じゃないとこの方法は出来ません。

  1. 解析解の表示
    1. 1次元のアニメーション
    2. 2次元のアニメーション
    3. 点をグラフ上に沿って動かす
    4. グラフをだんだんと書く
  2. データの表示
    1. 複数のデータを次々とプロット
    2. 複数のデータの同時プロット
    3. グラフをだんだんと書く
  3. 応用
    1. グラフを回転させる
    2. 大きさの違う球体
    3. PSO2の転送装置
    4. 「見せてあげよう!ラピュタの雷を!!」
    5. 魔女の宅急便
    6. 第5使徒ラミエル1
    7. 第5使徒ラミエル2
    8. 魔貫光殺砲
    9. マリオ
    10. SCP-1968 「世界を包む逆因果の円環」っぽい数式
    11. FGO召喚
    12. パンジャンドラム
  4. 動画の作成について
    1. gifアニメの作成方法
    2. ffmpegを用いてavi動画を作る

[adsense1]

1次元の場合の具体例


試しに量子力学で現れる、ガウシアン波束の時間発展を考えましょう。
こんな形の方程式を考えます。
\(
\displaystyle y(x,t)=\left(\frac{1}{1+t^2}\right)^{1/2}\exp\left[-\frac{(x-t)^2}{1+t^2}\right]
\)

これをgnuplot上で時間発展させるスクリプトはこちら。

do for [i = 0:400 ] {
   t=i*0.02
   plot sqrt(1/(1+t*t))*exp(-(x-t)**2/(1+t*t))
   }

適宜xrangeとかyrangeとか変更してください。実行するとこんな感じ。
gauss_low

上のgifアニメを得るには、

set term gif animate optimize delay 2 size 480,360
set output 'movie.gif'

do for [i = 0:400 ] {
   t=i*0.02
   plot sqrt(1/(1+t*t))*exp(-(x-t)**2/(1+t*t)) lw 2
   }

set out
set terminal wxt enhanced

というスクリプトを使ってください。
同ディレクトリにmovie.gifが作成されます。
ターミナルとかは各々の環境に合わせてください。

2次元の場合の具体例


2次元だろうとこのように簡単にできます。
gauss2d_analytic
上の動画のスクリプトはこれです。gifアニメが欲しい場合はコメントアウトを外してください。

#set term gif animate optimize delay 10 size 480,480
#set output 'movie.gif'

set pm3d at b
set xr[-5:10]
set yr[-5:10]
set zr[0:1]
set cbr[0:1]
set isosamples 50

do for [i = 0:50 ] {
   t=i*0.05
   splot sqrt(1/(1+t*t))*exp(-(x-t)**2/(1+t*t))*sqrt(1/(1+t*t))*exp(-(y-2*t)**2/(1+t*t))
   }

#set out
#set terminal wxt enhanced

点をグラフ上に沿って動かす


parameter
のような動画を作りたいとします。この時は、媒介変数を用いて以下のスクリプトで再現されます。

#set term gif animate optimize delay 5 size 960,720
#set output 'movie.gif'

set param
set size ratio -1
set samples 10000

e = 1
omega=0.1

set tr[1:600]
do for [i = 1:200 ] {  
   plot e*cos(omega*t)/sqrt(t), sin(omega*t)/sqrt(t)
   set label 1 point pt 7 ps 3  at e*cos(omega*i*3)/sqrt(i*3),sin(omega*i*3)/sqrt(i*3)
   }

#set out
#set terminal wxt enhanced

点の表示は、

set label 1 point pt 7 ps 3  at e*cos(omega*i*3)/sqrt(i*3),sin(omega*i*3)/sqrt(i*3)

の文である1点だけを表示することができます。

グラフをだんだんと書いていく


グラフをちょっとずつ書いていきます。
解析的な解の場合
orbit

set param
set samples 10000
set tr[0.01:1]
imax=100
tmax=20e0*pi
ht=tmax/real(imax)

#set term gif animate optimize delay 6 size 600,600
#set output 'orbit.gif'

do for [i=1:imax] {
   th(t,i)=t*real(i)*ht
   plot 10e0*sin(th(t,i))/th(t,i),10e0*cos(th(t,i))/th(t,i) , \
   10e0*sin(th(t,i)-pi)/th(t,i),10e0*cos(th(t,i)-pi)/th(t,i) lt 1 lc 2
}

#set out
#set terminal wxt enhanced

データの場合(200行のデータ”outgraph.d”を一行目から順番に出力したい場合)

do for [i=1:200]{
   plot "outgraph.d" every ::0:0:i:0 using 1:2 w l
}

グラフを回転させる


ある3Dプロットがあり、それを回転させてみるような動画がほしいとします。例えばこんな感じのアニメーションが作りたいとします。
Riemann
これはリーマン面と呼ばれる関数です。(カラーバーの消去は ‘unset colorbox’ とすれば消せます。)
詳しい記述は角度に依存して色を付ける(gnuplot)に書いてあるので気になる人は参照してください。

set pm3d depthorder
set parametric
set ur[0.01:5]
set vr[0:4*pi]
i={0,1}
splot u*cos(v),u*sin(v),real(sqrt(u)*exp(i*0.5*v))

#set term gif animate optimize size 480,360
#set output 'movie.gif'

do for [j = 0:90 ] {
   set view 60,4*j,1,1
   replot
}

#set out
#set terminal wxt enhanced

参考先はamesyabodyの記述したモンテカルロ法のページからです。

複数のデータを次々とプロット


複数のデータを時間経過を表示させる場合はデータfort.100, fort.101, fort.102,…を用意し、dofor構文の中を変えて、

#set term gif animate optimize size 480,360
#set output 'movie.gif'
do for [j = 100:200 ] {
   splot sprintf("./fort.%d", j) u 1:2:3 w l t sprintf("./fort.%d", j)
}

#set out
#set terminal wxt enhanced

してloadすればいいです。

複数グラフの同時プロット


gnulotofdata_c
data1.d, data2.d, data3.d,data4.d,data5.d
を同時に出力したい時は、

plot for [i=1:5] sprintf("data%d.d",i) w l ti sprintf("data%d.d",i)

とすればいいです。

大きさの違う球体


sphere3

PSO2の転送装置


PSO2の転送装置gnuplot

「見せてあげよう!ラピュタの雷を!!」


bulse2

魔女の宅急便


魔女の数式はこちらです。
witch like curve -wolfram alpha

kiki

第5使徒ラミエル1


ramiel

第5使徒ラミエル2


ramiel_trans

魔貫光殺砲


mk

マリオ


マリオのグラフは↓から。
Mario like curve -wolfram alpha

mario

[adsense2]

SCP-1968っぽい数式


SCP-1968 世界を包む逆因果の円環
に現れている数式です。
数式はTorus helix radius change equationより。

FGO召喚


特定の面と3D視点で見た場合

このリンク先(https://slpr.sakura.ne.jp/qp/supplement_data/FGO_gnuplot.zip)のデータも必要です。
(なんか良く分かりませんがメジェド様がバグるんですよね…)
▼ここクリックでこの場に展開

パンジャンドラム


gifアニメについて


gifアニメの描画時間を早くしたり遅くしたりするには、

set term gif animate delay 10 optimize size 480,360

などと「delay 10」という文を付け加えましょう。delayは遅延、後ろの数字は遅延時間で、単位は0.01sになっています。
例として、
delay 5の場合は1秒間に20枚、
delay 10の場合は1秒間に10枚、
delay 50の場合は1秒間に2枚
表示させるスピードだということです。
delayはどんなに早くしたくても4程度までがいいです。delayを1とかにするとそんなに早いgifアニメの描写が出来ず、ブラウザ上でうまく表示できず、結果として遅く表示されます。

Gif -gnuplot 4.2

ffmpegを用いてavi動画を作る


ffmpegのインストール方法はCompile FFmpeg on Ubuntu, Debian, or Mintを参考にしてください。
このページにもインストール方法を書きましたが、更新が早いので公式のページを見るほうが確実です。
ここではgnuplotの視点を変更した画像をたくさん用意して動画を作成する、という方法をとります。
ディレクトリ”dat/”と視点変更と連続した画像を出力するスクリプトは”image.plt”というファイルを用意して

do for [j = 0:180 ] {
   set view 60,2*j,0.5,3
   replot
   
   call "out.plt" "temp"
   
   if(0<=j && j<10){
      cv=sprintf("mv temp.jpg ./dat/image0000%d.jpg",j)
      }
   if(10<=j && j<100){
      cv=sprintf("mv temp.jpg ./dat/image000%d.jpg",j)
      }
   if(100<=j && j<1000){
      cv=sprintf("mv temp.jpg ./dat/image00%d.jpg",j)
      }
   if(1000<=j && j<10000){
      cv=sprintf("mv temp.jpg ./dat/image0%d.jpg",j)
      }
   if(10000<=j && j<100000){
      cv=sprintf("mv temp.jpg ./dat/image%d.jpg",j)
      }
   system cv   
}

#Using Imagemagick, convert
#cv=sprintf("convert -delay 20 -resize 100% -loop 0 ./dat/image*.jpg ./anime.gif")

#Using ffmpeg
cv=sprintf("ffmpeg -r 12 -i './dat/image%05d.jpg' -vcodec mjpeg -qscale 0 -s 1300x888 movieout.avi")
system cv

とすればディレクトリ./dat/の中に180枚の.jpg画像が作られ、その場所にファイル名”movieout.avi”という動画が作られます。


「gnuplotとアニメーション」への8件のフィードバック

  1. GNU plotってレポート用グラフ作成ツール程度にしか思ってなかったです・・
    スゴイ技ですねシェル芸はLinux界隈ではよく聞きますがGNU plot芸のほうがインパクトがすごいです

  2. 点をグラフに沿って動かす際の、「set label 1 point pt 7 ps 3 at e*cos(omega*i*3)/sqrt(i*3),sin(omega*i*3)/sqrt(i*3)」において、なぜtがi*3になるのですか??

    1. 特に”3”に理由はありません。
      動画にした時にいい感じの描画速度だったからです。
      もちろんt=iにしても構いませんが、それだと点の動くスピードが遅く、嫌だったのです。

  3. 学生時代にfortranで流体解析をした結果を表示する際にシキノートさんにお世話になりました。
    ITエンジニアとなったのですが、一つの技術をここまで極めて知識としてまとめていること尊敬します。

    ありがとうございました。

    1. コメントありがとうございます。
      どなたかが、特に学生が時間がない中で、私と同じあまり面白くない部分でつまづくことが無いようになればいいな、と
      いう思いもあり、実際にそのようなコメントを聞けて非常に嬉しい限りです。
      拙い部分が多くあったと思いますが、ご参照いただきありがとうございました。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です