Rubyでアニメーション・グラフを作ろう!

image

ベルマンフォードのアルゴリズムで実行される結果も逐次表示 - Seeking for my unique color.

を見てGraphVizの出力からアニメーションgifを作りたくなった Rubyにはruby-graphvizというGraphVizのinterface libraryと RMagickというImageMagickのinterface libraryがあり これらを使えば目的は達成できるみたいだ

ruby-graphvizのinterfaceは自分にはわかり辛かったので これをラップする形でGraphAz1というクラスを書いて 上のアニメーションgifを出力してみた 用途が限定的で実装にも問題がありそうだけれど GraphVizのDOTデータの出力としても使えるので 無責任無保証で使ってくれる人がいればうれしい

使い方

コードを見るのが早いと思うので 簡単な例を示した まずはDOTデータを作る例

require "graphaz"
routes = [
  ':main => :parse => :execute',
  ':main => :init',
  ':main => :cleanup',
  ':execute => :make_string',
  ':execute => :printf',
  ':init => :make_string',
  ':main => :printf',
  ':execute => :compare'
  ]
ga = GraphAz.new(:G)
routes.each { |route| ga.add route }
ga.print_graph

GraphAz.newでオブジェクトを生成し addメソッドで用意したルートを追加する addメソッドは対応するノードとエッジを同時に生成する 最後にprint_graphメソッドを呼べば DOTデータが標準出力に出力される

コマンドラインから以下のように実行すれば DOTファイルが生成される

> ruby small_graph.rb > small_graph.dot

pixelglow | graphviz などのツールで開けば以下のような グラフが得られるはずだ

image

今度はアニメーションgifを作成してみる コードを示す

require "graphaz"
routes = [
  ':main => :parse => :execute',
  ':main => :init',
  ':main => :cleanup',
  ':execute => :make_string',
  ':execute => :printf',
  ':init => :make_string',
  ':main => :printf',
  ':execute => :compare'
  ]
ga = GraphAz.new(:G)
routes.each { |route| ga.add route }
ga.lap
color = 'tomato'
ga.node('main', :style => 'filled', :fillcolor => color)
ga.lap
ga.edge('main_parse', :color => color)
ga.node('parse', :style => 'filled', :fillcolor => color)
ga.lap
ga.edge('parse_execute', :color => color)
ga.node('execute', :style => 'filled', :fillcolor => color)
ga.lap
ga.edge('execute_make_string', 'execute_compare', 'execute_printf', :color => color)
ga.node('make_string', 'compare', 'printf', :style => 'filled', :fillcolor => color)
ga.lap
ga.write

15行目までは同じで 16行目でprint_graphに代えてlapメソッドを使う lapメソッドはそこまでのコードに基づいて グラフをimageファイルとしてcurrent directoryに出力する2

次にnodeまたはedgeメソッドを使って グラフの属性を変化させる node,edgeメソッドは 複数のnode, edgeおよび属性を取ることができる その後lapメソッドを使ってそこまでの変化を出力する

これを繰り返し 最後にwriteメソッドを呼ぶことによって lapメソッドで出力したファイルを読み込み 1つのgifファイルout.gifを生成する 他のimageファイルはdefaultでは削除される

out.gifをブラウザなどで開き アニメーションgifが完成しているか確認する

image

ノードを後から追加するなどイメージデータのサイズが変わると うまくいかないなどの問題があります


(追記:2010-02-04) タイトルとrubyclass_graph.rbを修正しました

(追記:2010-02-18) Ruby1.9対応です。それ以前のRubyで使うときはnodeとedgeメソッドの第一引数の*を削除して配列を渡すようにしてください

(追記:2010-10-24) graphvizの0.9.9以降のヴァージョンではうまく動作しません。version0.9.8を使ってください

(追記:2010-10-25) graphviz ver.0.9.18に対応しました。clusterを表現できるようになりました。

melborne’s graphaz at master - GitHub



blog comments powered by Disqus
ruby_pack8

100円〜で好評発売中!
M'ELBORNE BOOKS