LoginSignup
1
2

More than 5 years have passed since last update.

Gnuplotを使ってGIF生成

Last updated at Posted at 2017-01-09

引き続き、ヴィジュアライズしたい。

RMagickを使ってGIF生成

ビジュアライズに限れば適当なplotを使えば良いのだろうけど、gifも欲しい。

どうもその適当なplotで十分GIF生成もできる様なのでお試し。

Gnuplot

ruby bindingがgemにあるのでinstall.
サンプルはあるがドキュメントは無いせいか、イマイチ使いにくい。
ソースを見てみるとやってることはシンプルで、薄いラッパー。
gnuplotコマンドに文字列を流し込んでいるだけ。
set term gif animateと相性が悪いだけで、他の用途なら問題無い気もする。

make_gif

set term gif animateとして、output先のファイル設定して、plotを繰り返せばアニメーションGIFに。

gnuplot_make_gif.rb
require "gnuplot"
def make_gif(name = "",x = 0,y = 0,fps = 0, &f)
  Gnuplot.open { |g|
    g << "set nokey\n"
    g << "set term gif animate\n"
    g << "set output \"#{name}\"\n"
    g << "set xrange [-1:#{x+1}]\n"
    g << "set yrange [-1:#{y+1}]\n"
    g << "set style line 1 lc \"green\" pt 7 ps 1\n"

    (1..fps).each { |n|
      cs = f.call(g,n)
      g << "plot \"-\" with points ls 1\n#{cs}"
    }
  }
end

lifegame

plotに渡すデータへ二次元配列を変換。ちょいめんどい。

require "./gnuplot_make_gif.rb"
require "./lifegame.rb"

lg = Lifegame.new(300,300)
lg.random

make_gif("gnuplot_lifegame.gif",300,300,100) { |io,n|
  io << "set style line 1 lc \"green\" pt 7 ps 0.25\n"
  io << "set title \"lifegame:#{n}\"\n"
  cs = lg.cells.map.with_index { |cy,iy|
    cy.map.with_index { |cx,ix|
      if cx == 1
        "#{ix} #{iy}"
      else
        nil
      end
    }.select { |a| a != nil }.join("\n")
  }.join("\n")
  cs << "\ne\n"
  lg.apply
  cs
}

gnuplot_lifegame.gif

end

この300*300*100のGIF生成に、私のPCでは70秒ほどかかります。
座標変換のコストがちょいかかってます。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2