読者です 読者をやめる 読者になる 読者になる

カタカタブログ

SIerで働くITエンジニアがカタカタした記録を残す技術ブログ。Java, Oracle Database, Linuxが中心です。たまにRuby on Railsなども。

R言語とImageMagickでgifアニメを作成

R言語で分布などをグラフィック生成される場合に、パラメータを少しずつ変えて微妙に変化するグラフィックをアニメーションさせて見てみたくなるときがよくある。
例えば、カイ二乗分布のような自由度ごとにグラフの形が大きく変わるようなものは、自由度を少しずつ変化させながらグラフの形状をアニメーションさせられるとより分かりやすい。教科書では、紙だとさすがにせいぜい2, 3個程度の代表的な値でのグラフを重ねて描くしかないが、R言語ならば動的なアニメーションを作成することも難しくなさそう。

手っ取り早くアニメーションを表示する方法として、gifファイルがシンプルでよさそう。ということで、今回は2通りの方法でRグラフィックをgifアニメとして作成してみた。

Rのanimationパッケージを使う

Rで作った画像をアニメーションとして作成するには、animationパッケージを使うのが一般的らしい。これを使うと、gifアニメーションだけでなく、HTMLやmpeg4などでの出力も可能らしい。ちなみにgifを作るためにはImageMagickというツールが必要なので、あらかじめインストールしておく。

事前にanimationパッケージをインストールする。

install.packages("animation")

そして、以下の様にsaveGIF関数の中にグラフィックを生成する処理を複数回呼び出す実装をすることで、アニメーションファイルが作成される。

library(animation)
saveGIF({
  ani.options(loop = TRUE)
  for (i in 1:5) {
    .main = paste("カイ二乗分布 自由度=", i, seq="")
    curve(dchisq(x, df=i), xlim=c(0,10), ylim=c(0, 0.3), main=.main)
  }
}, movie.name="chi.gif", interval=0.5)

この方法で、以下のようなgifアニメが作成できる。
f:id:osn_th:20160418085712g:plain

Rで画像を保存して直接ImageMagickを使う

animationパッケージが内部的に行っているのは、画像を出力し、ImageMagick(convertコマンド)で画像を一つのgifアニメーションファイルに変換しているので、同じことをR標準機能とコマンドでも行ってみる。

まず、以下のようにpng関数とdev.off関数でPNG画像ファイルを生成する。

for (i in seq(10, 100, 10)) {
  .main = paste("カイ二乗分布 自由度=", i, seq="")
  .file <- paste("out/chi", sprintf("%03d", i), ".png", sep="")
  png(.file)
  curve(dchisq(x, df=i), xlim=c(0,200), main=.main)
  dev.off()
}

このコードを実行することで、以下のようにoutディレクトリにpngファイルが作成される。

$ ls out
chi010.png chi030.png chi050.png chi070.png chi090.png
chi020.png chi040.png chi060.png chi080.png chi100.png

これをconvertコマンドで一つのgifファイルにまとめる。delayオプションでアニメーション切り替わりの間隔の時間を指定できる(単位は1/100秒なので、50を指定した場合は0.5秒)。

$ convert -delay 50 out/*.png out/chi2.gif
$ ls out/chi2.gif
out/chi2.gif

このコマンドで生成されたgifファイルは以下。
f:id:osn_th:20160416130726g:plain

まとめ

animationパッケージとImageMagickを直接使うことでRが生成したグラフィックをアニメーションさせる二通りの方法を見た。パラメータを少しずつ変えながら動的にグラフィックを表示させることで、よりデータの理解がしやすくなる場面も多そう。

以上