Shunsuke A. Sato

Gnuplotを使って動画を作ってみよう

(最終更新日:2022/06/20)

ここでは、Fortran等を用いた数値計算の実習する際に、gnuplotとImageMagicを使って計算結果から動画を作成する方法を解説します。

以下では、「1. Fortranによる連番ファイルの出力」、「2. gnuplotによる画像ファイルの出力」、「3. ImageMagickによる画像の結合」の3ステップを通じて、数値計算結果を動画として可視化する方法を学びます。


1. Fortranによる連番ファイルの出力

ここでは、まずFortranを使って、連番ファイルを作る方法について学びます。Fortranのdoループを用いると、ファイル名に連続する番号が付けられたファイルの複数用意することが出来ます。例題として、下記のFortranプログラムをコンパイル・実行してみましょう。

program main
  implicit none
  integer :: Nx,Nt,ix,it
  real(8) :: Xf,Tf,dx,dt
  real(8) :: f,t,x
  character(50) :: cit,filename
  Xf=10d0
  Tf=10d0
  Nt=50
  Nx=100

  dx=Xf/Nx
  dt=Tf/Nt

  do it=1,Nt
     t=dt*it
     
     write(cit,'(I7.7)')it
     filename=trim('anim_')//trim(cit)//'.dat'
! Writing a data file

     open(20,file=filename)
     do ix=1,Nx
        x=dx*ix
        f=sin(x-t)
        write(20,'(3e16.6E3)')x,f
     end do
     close(20)
  end do

end program main
上記のプログラムをコンパイル・実行するとanim_xxxxxxx.datという50個のデータファイルが出力されます。それぞれのデータファイルには、異なる時刻\(t\)に対する関数\(f(x,t)=\sin(x-t)\)の値が座標\(x\)の関数として格納されています。ファイルの第一列目は座標\(x\)の値、第二列目は関数\(f(x,t)=\sin(x-t)\)の値を記録しており、ファイル名に含まれる整数値が時刻\(t\)と関連付けられています。上記のFortranコードは、時間\(t\)に対するdoループと座標\(x\)に対するdoの二重doループから成っており、外側のdo it=1,Ntから始まるdoループでは、各ステップでopen(20,file=filename)によってファイルを開き、そのファイルへ三角関数の情報を書き込んでいます。各ステップのitについて、write(cit,'(I7.7)')itによって整数型変数itから文字型変数citへの変換を行い、カウンターitの整数を含むようなファイル名をfilename=trim('anim_')//trim(cit)//'.dat'によって作っています。do ix=1,Nxから始まる内側のdoループでは、三角関数を座標\(x\)の関数としてそれぞれのファイルに書き出しています。




2. gnuplotによる画像ファイルの出力

次に、上記で作られた連番のデータファイルから、gnuplotを用いて連番の画像ファイルを作る方法を解説します。ここでは、gnuplotのwhile文を用いて、データファイルから画像ファイルへ変換することを考えます。例として、次のようなgnuplotのスクリプトを考えます。このスクリプトをテキストエディタを使ってplot.pltと名前を付けて保存し、ターミナル上でgnuplot plot.pltと入力することで、gnuplotにスクリプトを読ませ、スクリプトを実行させることが出来ます。上記で作られた連番ファイルが準備されていれば、下記のgnuplotスクリプトを実行することで50個の画像ファイル(gifファイル)が生成されます。

set term gif

set yrange [-1.0:1.0]

j = 0
while (j<50){
j = j+1
filename_data = "anim_".sprintf('%07.0f.dat', j)
filename_gif = "anim_".sprintf('%07.0f.gif', j)

set output filename_gif
p filename_data u 1:2 w l

unset output

}
ここでは、簡単に上記のgnuplotスクリプトについて解説します。スクリプトは、gnuplotに読ませることで上から順番にコマンドを実行させることが出来ます。先頭のset term gifは、gif形式の画像ファイルを出力するための出力形式の設定を行っています。次のset yrange [-1.0:1.0]では、y軸の描画範囲を[-1.0:1.0]の範囲で固定しています。次にj = 0にてループのカウンターをゼロに初期化し、while文を用いてそれ以降の処理を繰り返し行っています。ここで、while (j<50){}は、jが50よち小さい間だけ、次の操作を繰り返す文となっています。そのすぐ後にj=j+1によってループのカウンター変数を1増加させ処理を進めていきます。filename_data = "anim_".sprintf('%07.0f.dat', j)filename_gif = "anim_".sprintf('%07.0f.gif', j)の文では、整数j文字列に変換し、データファイル(.dat)と画像ファイル(.gif)のファイル名に組み込んでいます。その次の、set output filename_gifでは出力するファイルの名前を設定し、さらにp filename_data u 1:2 w lにてデータファイルから画像ファイルへの出力を行っています。この操作をjを1から50まで繰り返すことで、連番のデータファイルから連番の画像ファイルを作ることが出来ます。




3. ImageMagickによる画像の結合

次に、上記の操作で作られた連番の画像ファイルをImageMagickにより結合することで、動画の作成を行います。まず、ImageMagickがCygwinにインストールされているかを確認するためにコマンドconvert -versionをターミナル上で実行してみます。無事にImageMagickのバージョンが表示されていれば、ImageMagickはCygwinにインストールされています。ImageMagickがインストールされていない場合は、Cygwinのインストールページを参考にImageMagickをインストールしてください。

ImageMagickの準備が整ったら、序機で用意した連番の画像ファイルがあるディレクトリ内でconvert -delay 10 -loop 0 anim_*.gif anim.gifを実行してみましょう。ここでは、convertはImageMagickにおけるファイル変換のプログラムであり、anim_*.gifで表される連番の画像ファイルを結合することでanim.gifというgifのアニメーションファイルが作成されます。convertのオプションである-delayは、連結されたファイルの移り変わる速さを決めるオプションであり、-loop 0は連結されたgifアニメーションを無限にループすることを表すオプションです。上記の一連の操作によって下に示したようなgifのアニメーションが作成されているはずです。この方法を応用して、数値計算の結果を可視化してみましょう。

gif animation