GMTで描こう Part 5: movie

movieモジュールでアニメーションを作る

orbit_loop.gif

はじめに

 本稿ではGMT6で新たに追加された機能である、movieモジュールを紹介していきます。GMT5以前のバージョンでは、ユーザーがそれぞれ書いていた独自のスクリプトで動画が作成されていましたが、新機能ではシェルスクリプトの記述が整理されて可読性の高い記述ができるようになっています。

 movieモジュールで出力される動画とは、他のモジュールによるプロットをフレームとして連続的に並べたものです。ここでのフレームとは、動画を構成する静止画1枚のことをさしています。動画(またはアニメーション)とは、似ているけれど少し異なる(変化した)フレームを並べることにより、連続的な意味のある動画として成り立ちます。

4つの必須な引数

movieモジュールによる動画化は次のようなコマンドを実行します。

$ gmt movie mainscript -Ccanvas -Ttimefile -Nname [other options ...]

mainscript

 mainscriptは、個々のフレームをプロットするスクリプトのファイル名です。このスクリプトはGMTモダンモードで記述されて、似ていながら少しずつ異なるプロットを、フレーム変数を使用して大量に作成します。movieモジュールは、与えられたmainscriptと同じスクリプト言語(.sh, .bash, .csh, .batのいずれか)を使って、これを元に個別のプロットを行うスクリプトを生成します。フレーム変数については後述します。

C

 このオプションではフレームを作成する際に使われるキャンバスサイズ(描画範囲の寸法)を指定します。キャンバスサイズの指定には名前付きプリセットフォーマットを選択するか、または幅/高さ/dpuを与えることでカスタムフォーマットを選択することができます(dpuはdots-per-unit, つまり単位あたりピクセルでdots-per-inchかdots-per-cmを指します)。Appendixにプリセットフォーマットの一覧表を載せておきます。
 カスタムフォーマットで指定する際には、幅と高さとdpuをwidthxheightxdpuのように指定します。widthheightは単位付きの数値で、dpuは単位なしで指定します。区切り文字は小文字のエックスです。

例 4Kの大きさにする場合:-C2160-C4kまたは-Cuhd
  600 x 600ピクセルの大きさにする場合:-C6cx6cx100-C6ix6ix100など

-N

最終的に出力されるムービーファイルの名前と、フレーム画像を保存するサブディレクトリの名前を、-Nnameの形式で記述します。

-T

-Tオプションはアニメーションのフレームの数について設定するオプションで、その設定方法には2種類あります。

  1. 作成する静止画フレームの数を指定する。
  2. 1フレームあたり1レコードのパラメーターセット(行)を持つファイルtimefileを指定する。

 1の方法では、-T360のように整数を付加します。この場合0番から359番までのフレームが生成されます。
 2の方法では、timefileに含まれる列の値について、名前付きのパラメーターを使ってmainscriptからアクセスできます。timefileのレコードの数はアニメーションのフレーム数に等しくなります。

パラメーター

 コマンドを実行する際に、いくつかのパラメーターは自動的に割り当てられて、メインスクリプトや背景/前景スクリプト(後述)で使用することができます。パラメーターには、定数なものとフレーム番号に依存するものの2種類があります。

定数

定数には全てのスクリプトからアクセスできます。

  • MOVIE_WIDTH:キャンバスの幅
  • MOVIE_HEIGHT:キャンバスの高さ
  • MOVIE_DPU:単位長さあたりのドット数
  • MOVIE_RATE:1秒あたりのフレーム数
  • MOVIE_NFRAMES:フレームの総数
フレーム依存パラメーター

フレーム依存パラメーターにはメインスクリプトからアクセス可能です。

  • MOVIE_FRAME:現在のフレーム番号(136などの整数)
  • MOVIE_TAG:0埋めされた書式のフレーム番号(000136などの文字列)
  • MOVIE_NAME:現在のフレームの名前(例:”name_000136″)

加えてtimefileが指定されている場合には、前述の通り、MOVIE_COL0, MOVIE_COL1, … などが設定されて、timefileの列ごとに1つのパラメーターが生成されます。timefileの行の末尾に文字列がある場合には、MOVIE_TEXTを使ってスクリプトからアクセスできます。

背景スクリプトと前景スクリプト

 背景スクリプト(background)と前景スクリプト(foreground) は、mainscriptと同じ言語で書かれたスクリプトで、変化しない静的な背景/前景のプロットを作ります。全てのフレームに共通する絵を背景/前景として与えることにより、mainscriptは動的なもののプロットに集中できるので、全体の描画コストを節約できます。また背景スクリプトは、mainscriptで必要となるtimefileのようなファイルを生成することもできます。

 背景スクリプトは-Sbbackground、前景スクリプトは-Sfforegroundでスクリプトファイルを指定します。

 

backgroundforegroundを指定してプロットする場合には、正しい位置で重ねることができるように、mainscriptと同じ位置のオフセット(-X, -Yオプション)を与える必要があります。

例:円運動

単位円を周回する点のアニメーションを作成します。背景スクリプトは以下の通りです。

#!/bin/bash
gmt math -T0/360/2 T COSD = x.txt
gmt math -T0/360/2 T SIND = y.txt
gmt convert x.txt y.txt -A -o1,3 >> circle.txt
gmt begin
   gmt basemap -JX10c -R-2/2/-2/2 -BWeSn -Bxagf -Byagf -X1c -Y1c
   gmt plot circle.txt -W1p
gmt end

2, 3行めでそれぞれx座標とy座標の値を生成し、4行めでそれらを2列のデータに整形し、circle.txtに出力しています。次にbasemapでグラフの枠を書き出し、circle.txtファイルを使って単位円を描画しています。

 メインスクリプトは以下の通りです。

#!/bin/bash
gmt begin
   gmt plot -JX10c -R-2/2/-2/2 -Sc0.3c -Gred -X1c -Y1c <<< "${MOVIE_COL0} ${MOVIE_COL1}"
gmt end

-J, -R, -X, -Yのオプションは背景スクリプトと同じものを与えています。ここではヒアストリングを利用して、直径0.3cmの赤い点を、timefileで与えられるであろう現在の座標にプロットするように指示しています。

実行するコマンドは次のようになります。

$ gmt movie main.sh -Sbbg.sh -C12cx12cx50 -Norbit -Tcircle.text -A+l

-AオプションはムービーをGIFアニメーションとして出力するという指示で、後ろの+lはアニメーションをループさせるという意味です。

結果として次のGIFファイル orbit.gif が出力されます。

orbit_loop.gif

例:地球儀

 Documentationの例を参考に、ちょっと変更して描画してみます。地球儀のアニメーションの描画です。メインスクリプトは次の通りで、背景/前景スクリプトはありません。

#!/bin/bash
gmt begin
   gmt coast -Rg -JG${MOVIE_FRAME}/20/${MOVIE_WIDTH} -Gmaroon -Sturquoise -Bg -X0 -Y0
gmt end
  • -Rgは描画範囲を全球(経度0から360度、緯度-90から90度)と指定しています。
  • -JGは正射図法を選択しています。描画の中心として経度はフレーム番号、緯度は北緯20度とすることで、地球儀を回すようなプロットを行います。描画の大きさはMOVIE_WIDTHつまりキャンバスの幅いっぱいとしています。
  • 塗りつぶしは、陸域をマルーンに、水域をターコイズに指定しています。

実行するコマンドは次のとおりです(結構重たい処理なので、実行する際は注意してください)。

$ gmt movie globe.sh -Nglobe -T360 -C6ix6ix100 -Lf -P -A+l

 上のコマンドでは、-Tオプションでフレーム数360を与えて、ちょうど地球一周のプロットをするようにしています。-Lfはフレームラベルの設定です。個別のフレームにフレーム番号を自動的に振ってくれます(左上)。-Pはアニメーションの進行度合いを表示するインジケーターの設定です。GMTに用意された6種類のインジケーターのうち、円グラフ型のデフォルトのものを描画しています(右上)。

例:Sineカーブ

 DocumentationにおいてAnimetionの例(1)として挙げられているサインカーブのアニメーションを作りたいと思います。リンク先に掲載されているスクリプトを改変して、以下の2つのシェルスクリプトを用意しました。

#!/bin/bash
gmt math -T0/360/20 T SIND = sin_point.txt
gmt math -T0/360/2 T SIND = sin_curve.txt
gmt begin
   basemap -R0/360/-1.2/1.6 -JX3.5i/1.65i -X0.35i -Y0.25i \
      -BWeSn+glightgreen -Bxa90g90f30+u@. -Bya0.5f0.1g1 --FONT_ANNOT_PRIMARY=9p
gmt end
#!/bin/bash
# 'gmt movie'のコマンドで, timefileとしてsin_point.txtを-Tに渡す予定
gmt begin
   # すべての角度ステップで、その時点までの滑らかな青い曲線と濃い赤の点をプロットする
   last=$(gmt math -Q ${MOVIE_FRAME} 10 MUL =)   # シェル変数lastにMOVIE_FRAMEの10倍の数の1列リストを格納する
   gmt convert sin_curve.txt -Z0:${last} | gmt plot -W1p,blue -R0/360/-1.2/1.6 -JX3.5i/1.65i -X0.35i -Y0.25i
   gmt convert sin_point.txt -Z0:${MOVIE_FRAME} | gmt plot -Sc0.1i -Gdarkred

   # 現在の角度について明るい赤の点をプロットし、注釈をつける。
   gmt plot -Sc0.1i -Gred <<< "${MOVIE_COL0} ${MOVIE_COL1}"   # ヒアストリングで現在の(x,y)を入力している
   print "0 1.6 a = %3.3d" ${MOVIE_COL0} | gmt text -F+f14p,Helvetica-Bold+jTL -N -Dj0.1i/0.05i
gmt end

 pre.shの6行目について、-Bxオプションの後ろに指定されている+u@.は軸の単位を度数表記にする命令であり、一方で--FONT_ANNOT_PRIMARY=9pは、GMTで自動的に設定されるプライマリーアノテーション(軸の数字)の大きさを手動で9ポイントに設定しています。

 main.shで、曲線をプロットするsin_curve.txtのconvert-Zに渡されるシェル変数lastを作成しているのは次の理由によるものです。
まず、sin_point.txtはxが20ごとのファイルで、sin_curve.txtは2ごとのファイルであり、データレコード数の開きは10倍になっています。そのため、i番目のフレームで曲線をx = i*20まで描画したいときには、sin_curve.txt中の必要なデータレコードの数はi*10個となるわけです。convert-Zオプションでデータを切り出す際には、レコード番号を指定する点に注意してください。
 一方で、timefileとしてsin_point.txtを渡すので、変数MOVIE_COL0はフレームが進むにしたがって、0, 20, 40, …となっていきます。7行目で濃い赤点をプロットする際には、(フレーム番号)=(描画したい範囲のレコード番号)となるので、-Zオプションの終端としてMOVIE_FRAMEをそのまま使用できます。

 main.shの11行目にはtextモジュールが使用されていますが、これについては後日記事を書く予定です。ここでの要点は、textモジュールはその名の通り文字列を描画するもので、入力としてx, y, 文字列を受け取ります。-Fでフォントのディテール(大きさ、フォント名、大まかな位置)を指定して-Djで細かな位置調整をしています。

 動画化を実行するコマンドの例は次の通りです。

$ gmt movie main.sh -Sbpre.sh -C4ix2ix125 -Tsin_point.txt -Nanim01 -D5 -A+l

以下のanim01.gifが出力されます。

anim01.gif

その他のオプション

  • -D:出力するアニメーションのフレームレートをFPS(frame per seconds)で設定します。
  • -F:出力するファイル形式として、mp4webmのどちらかを指定します。

 このほかにも様々なオプションが用意されています。

まとめ

 今回はアニメーションの作成について扱いました。3つのアニメーションを紹介しましたが、どれも基本機能しか使っていません。GMT6にはモダンモードが追加され、movieモジュールが提供されるようになってから動画出力のハードルは下がったように感じられます。公式ドキュメントのAnimationのページには他にもたくさんの動画が公開されているので、ぜひ見てみてください。

Appendix

キャンバスサイズのプリセットフォーマット

 16:9のプリセットフォーマットのキャンバスのサイズは24×13.5 cmまたは9.6×5.4 inchです。以下にピクセル寸法と-Cオプションに与える名前との対応表を示します。

ピクセル寸法名前
7680 x 43204320p, 8k, uhd-2
3840 x 21602160p, 4k, uhd
1920 x 10801080p, hd
1280 x 720720p
960 x 540540p
854 x 480480p
640 x 360360p
426 x 240240p

 4:3のプリセットフォーマットでは、24×18 cmまたは9.6×7.2 inchです。

ピクセル寸法名前
1600 x 1200uxga
1400 x 1050sxga+
1024 x 768xga
800 x 600svga
640 x 480dvd

参考文献

  1. movie — GMT 6.2.0rc1 documentation
  2. (1) Animation of the sine function — GMT 6.2.0rc1 documentation
  3. gmt.conf — GMT 6.2.0rc2 documentation # FONT_ANNOT_PRIMARY
  4. General Features — GMT 6.2.0rc2 documentation CookBook

コメントを残す

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