Gvizの目次 - Rubyの世界からGraphvizの世界にこんにちは!
このブログにはGvizに関する大量の記述があるのだけれどもまともにタグ付けされてないサイト検索もできないと非常にアクセスビリティの悪い有り様でまあ本来なら気合を入れてひとつその全体解説たる記事を書き下ろしてここに公開!と宣言してついでにEPUBにまとめて一攫千金と相成りたいところ如何せん筆がぁ筆がぁっつって一向に気持ちがそちら方面に向かわずにおるわけで。
そこで代わりといってはなんですが「Gvizの目次 - Rubyの世界からGraphvizの世界にこんにちは!」と題して過去の記事をここにまとめて一覧できるように致しましたのでGvizをご利用頂いていていままで右往左往させられていた方あるいは使い方がわからん何が描けるのかわからん全く意味がわからんという方あるいは将来においてGvizに興味を持たれる可能性のある方居られましたら是非ともこのページを基点として各ページに飛んで頂きたくお願い申し上げます。
っていってそれじゃあまりにあまりお前のゆーざふれんどり精神あるいはおもてなしの心どこいったという精神内紛が勃発惹起されてしまったので仕方なく前置きくらいは書いておくかと書き始めてみたら筆がぁ筆がぁって走りだしてそれなりに長い記事になりましたが最後までお付き合いのほどよろしくね。
Graphvizって何?
GraphvizはAT&T研究所が開発したオープンソースのグラフ描画ツールパッケージです。ここでいうグラフはExcelでいうところのグラフではなくグラフ理論でいうところのグラフです。ノードという玉とエッジという線を繋いだ体のもので、依然「?」な人はフローチャートや家系図をイメージしてください。Excelのグラフは数字を比較可能にビジュアライズします。一方で、Graphvizのグラフは「物事の関係性」をビジュアライズします。
Graphvizは、DOT言語という専用言語で記述された物事の関係性を読み込んで、これを描画出力します。png, jpeg, bmp, pdf, svgなど多様な画像フォーマットへの変換機能を持っています。プラットフォームに合ったものをここからダウンロードして、エディタで以下のようなファイルを書きます。
/* sample.dot */
digraph G {
GrandpaA -> Papa;
GrandmaA -> Papa;
GrandpaB -> Mama;
GrandmaB -> Mama;
Papa -> You;
Mama -> You;
}
ファイルを開くと、
% open sample.dot
Graphvizソフトが立ち上がって、次のような出力が得られます。
任意の画像フォーマットへの変換はコマンドラインツールでも、Graphvizソフトのexport機能を使ってもできます。
Graphvizの最大の特徴は、例のように関係性を記述すればその配置はGraphviz側でよしなにやってくれることです。一方でそれがGraphvizの最大の弱点にもなっています。個々のノードの配置を望み通りにコントロールするのは困難です。しかし手段がないわけではありません。
ノードの配置その1
Graphvizはその大枠としてのレイアウトの指定ができます。デフォルトはdot
ですが、fdp
, neato
, circo
, osage
などその名前からは配置が全く想像できないwレイアウトが使えます。
layoutにneato
を指定してみます。
digraph G {
layout=neato; /* レイアウトの指定 */
GrandpaA -> Papa;
GrandmaA -> Papa;
GrandpaB -> Mama;
GrandmaB -> Mama;
Papa -> You;
Mama -> You;
}
出力は以下のように変わります。
ノードの配置その2
rankdir
属性でレイアウトの向きというのを変えることができます。
左から右(LR)を指定してみます。
digraph G {
rankdir=LR; // 左から右へ
GrandpaA -> Papa;
GrandmaA -> Papa;
GrandpaB -> Mama;
GrandmaB -> Mama;
Papa -> You;
Mama -> You;
}
出力です。
ノードの配置その3
rank
属性でレイアウトにおけるノードの並び順位を指定できます。
digraph G {
GrandpaA -> Papa;
GrandmaA -> Papa;
GrandpaB -> Mama;
GrandmaB -> Mama;
Papa -> You;
Mama -> You;
{ rank=same; Papa; GrandmaA } // これらを同じランクに
{ rank=same; Mama; GrandmaB }
{ rank=min; You } // 最小ランクに
}
出力です。
ノードの配置その4
究極の配置手段として絶対位置指定pos
属性があります。これはfdp
, neato
などのレイアウトで有効になります。
digraph G {
layout=neato;
GrandpaA -> Papa;
GrandmaA -> Papa;
GrandpaB -> Mama;
GrandmaB -> Mama;
Papa -> You;
Mama -> You;
You [pos="0,0!"];
Papa [pos="100,100!"];
Mama [pos="0,-100!"];
GrandmaA [pos="100,0!"];
GrandmaB [pos="-100,0!"];
GrandpaB [pos="100,-100!"];
GrandpaA [pos="-100,100!"];
}
出力です。
属性指定
Graphvizのもう一つの大きな特徴は、多様な属性指定ができることです。グラフ全体、ノード、エッジなどに対して細かい属性指定が可能です。
先のグラフにいろいろと属性を指定してみます。
digraph G {
bgcolor="cornsilk";
node [shape=egg];
GrandpaA -> Papa [style=dotted];
GrandmaA -> Papa [arrowhead="odiamond"];
GrandpaB -> Mama;
GrandmaB -> Mama [color="red"];
Papa -> You;
Mama -> You;
You [shape=doublecircle, style=filled, fillcolor="orange"];
Papa [shape=house, style="filled", color="purple", fontcolor="white", label="パパ"];
Mama [shape=invhouse, style="filled", color="pink", label="ママ"];
}
出力です。
色
上で見たようにGraphvizではノード、エッジ、背景に自由に色を付けられます。簡単にかつ美しい色付けをしたい場合はcolorscheme
属性が便利です。
digraph G {
node [style=filled, colorscheme=rdpu3];
GrandpaA -> Papa;
GrandmaA -> Papa;
GrandpaB -> Mama;
GrandmaB -> Mama;
Papa -> You;
Mama -> You;
You [style=filled, fillcolor=1];
Papa [style=filled, fillcolor=2];
Mama [style=filled, fillcolor=2];
GrandmaA [style=filled, fillcolor=3];
GrandmaB [style=filled, fillcolor=3];
GrandpaB [style=filled, fillcolor=3];
GrandpaA [style=filled, fillcolor=3];
}
出力です。
文献
使えるレイアウト、属性、色などの情報は本家サイトのドキュメントを見るのが早いです。
まとまった資料としては以下のPDF(英語版)があります。2006年版ということでちょっと古いです。
さらに古い2003年版を対象にしたものですが、日本語版を作られた方がいます。
Gvizって何?
GvizはDOT言語を使わずにRubyのコード(DSL)を書くことでGraphvizによるグラフ描画を可能にするライブラリ&コマンドラインツールです。つまりRubyのコードをDOT言語によるコードに変換するコンバータです。DOT言語は制御構造を持っていないので、ノード数の多い複雑なグラフやプログラムに読み込めるデータに基づくグラフを描画する場合には、Gvizを使ったほうが圧倒的に早く仕事を終わらせられます。
Rubyによる同種のプログラムは多数存在します。古くからあって最も人気のあるものは「ruby-graphviz」です。比較的新しくて人気のあるものにRyan Davisの「graph」があります。Gvizはgraphにインスパイアされて作りました。私見ですがruby-graphvizはRuby成分が少なくgraphはtoo much DSLなので、Gvizは「ほどよいDSL」のインタフェースを目指しました。最新バージョンは0.3.4、Rubyは2.0.0以上が必要です。
Gvizの使い方
2種類の使い方、つまりプログラムからの使い方とコマンドラインインタフェース(CLI)を通しての使い方があります。まずはgem install gviz
します。
プログラムから
この記事の最初のサンプルをrubyで書いてみます。
# sample.rb
require 'gviz'
gv = Gviz.new
gv.add %i(GrandpaA GrandmaA) => :Papa
gv.add %i(GrandpaB GrandmaB) => :Mama
gv.add %i(Papa Mama) => :You
gv.save :sample, :png
add
メソッド(またはroute)にHashを渡してノード同士のつなぎを指定します。各ノード名はSymbolの必要があります。渡されるHashのキー、バリュとしてこのように配列を指定できます。ここではaddを3回呼んでいますが、すべてのつなぎを一つのaddに渡しても構いません。
save
メソッドの第1引数に出力ファイル名を、第2引数に画像フォーマットを渡します。第2引数を省略した場合はdotファイルだけが出力されます。
このファイルを実行すれば、
% ruby sample.rb
% open sample.dot #または sample.png
次の出力が得られます。
GvizはGraph
というトップレベルのショートカット関数を持っているので、上のコードは次のようにDSLを使ってより簡潔に記述できます。
# sample.rb
require 'gviz'
Graph do
add %i(GrandpaA GrandmaA) => :Papa
add %i(GrandpaB GrandmaB) => :Mama
add %i(Papa Mama) => :You
save :sample, :png
end
CLIから
Gvizをインストールするとターミナルでgviz
コマンドが使えるようになります。
% gviz
Gviz is a tool for generating graphviz dot data with simple Ruby's syntax.
It works with a graph spec file (defaulting to load 'graph.ru').
Example of graph.ru:
route :main => [:init, :parse, :cleanup, :printf]
route :init => :make, :parse => :execute
route :execute => [:make, :compare, :printf]
save(:sample, :png)
Commands:
gviz build [FILE] # Build a graphviz dot data based on a file
gviz help [COMMAND] # Describe available commands or one specific command
gviz man [NAME] # Show available attributes, constants, colors for graphviz
gviz version # Show Gviz version
graph.ru
という名前で次のように記述します。
#graph.ru
add %i(GrandpaA GrandmaA) => :Papa
add %i(GrandpaB GrandmaB) => :Mama
add %i(Papa Mama) => :You
save :sample, :png
ファイルのディレクトリでgviz build
コマンドを実行します。
% gviz build
% open sample.png
省略しますが同様の結果が得られます。
先の属性を指定した例も示します。
#graph.ru
global bgcolor:"cornsilk"
nodes shape:"egg"
add %i(GrandpaA GrandmaA) => :Papa
add %i(GrandpaB GrandmaB) => :Mama
add %i(Papa Mama) => :You
node :You, shape:"doublecircle", style:"filled", fillcolor:"orange"
node :Papa, shape:"house", style:"filled", color:"purple", fontcolor:"white", label:"パパ"
node :Mama, shape:"invhouse", style:"filled", color:"pink", label:"ママ"
edge :GrandpaA_Papa, style:"dotted"
edge :GrandmaA_Papa, arrowhead:"odiamond"
edge :GrandmaB_Mama, color:"red"
save :sample
global
メソッドでグラフ全体の属性を指定します。nodes
メソッドでノード全体の、またここでは出てきませんがedges
メソッドでエッジ全体の属性を指定します。
各ノード、エッジの属性指定はそれぞれnode
, edge
メソッドを使います。第1引数はidでありlabel属性がなければラベルとしても使われます。idはSymbolでなければならず、エッジのidはノードのidを_
(アンダーバー)で結んだものになります。ここでは使われていませんが、Object#to_id
を使って任意のオブジェクトからidを生成することができます。
Rubyの図
Rubyらしい図も書いてみます。
klasses = [Class, String, Symbol, Array, Hash, Fixnum, Bignum]
nodes shape:'box3d', colorscheme:'blues8', style:'filled'
klasses.each do |klass|
klass.ancestors.reverse.each_cons(2).with_index(1) do |ab, i|
a, b = ab.map { |n| :"#{n}" }
route a => b
node b, fillcolor:i%9
edge [a, b] * '_', color:'maroon'
end
end
save :ruby, :png
Module#ancestorsを使ってRubyのメソッド探索ルートをグラフ化します。普通にRubyのコードが書けます。
出力です。
いいですね。
Gvizの他の機能やどんなグラフや図が描けるのかについては、以下の記事一覧から辿って該当記事を読んでください。
ブログ記事一覧
このブログにおいてGvizに関連する記事は以下になります(時系列昇順)。現時点で28件ありますが今後も新しい記事が書かれた際はここに追加します。
各記事の概要説明
記事の検索性を上げるためその概要も書いておきます。あらためて、なんというかGraphvizの本来の使い方とかけ離れた使い方ばかりで…。あまり参考にならないかもしれません。
1. Yet Another Ruby Graphviz Interfaceを作ったからみんなで大量のグラフを作って遊ぼうよ!
この記事ではGvizを公開したこと、その基本機能の説明およびサンプルとして次のような日本地図を描きました。
2. Ruby Graphvizラッパー「Gviz」でアメリカ合衆国をデータビジュアライズしよう!
この記事ではアメリカ合衆国の各州の統合年、面積および人口を、ノードの色、大きさおよび多角形の辺の数を使ってビジュアライズしました。
3. 東京の地下鉄をGviz(Ruby Graphviz Wrapper)で描く
この記事では、『駅データ.jp』が提供する路線情報を使って、東京の地下鉄路線図をビジュアライズしました。ここでは駅の緯度・経度情報から正しい位置に駅ノードを配置しています。
4. 東京の地下鉄の路線サインをGviz(Ruby Graphviz Wrapper)で描く
この記事では、東京の地下鉄の路線サインを描画しました。
5. プログラミング言語にも案内サインシステムを!
この記事では、地下鉄の路線サインにヒントを得て、プログラミング言語のサインを作ってみました。
6. 素数とフィボナッチ数の出会いをGviz(Ruby Graphviz Wrapper)で描く
この記事では、Rubyで素数とフィボナッチ数を出力してそれが交わる様子をグラフ化してみました。
7. GvizでAKB48をビジュアライズするよ!
この記事では、Gvizに追加された(1)Gvizコマンド、(2)multiple edge指定、(3)Object#idの機能の紹介と、AKB48のメンバー名をグラフ化した例を載せました。
8. GvizでGraphvizのノードの形とかエッジの形とか使える色の名前とかの属性情報をゲットするよ!
この記事では、Gvizに追加された(1)gviz man
コマンド、(2)Graphvizの属性情報定数の紹介と、属性情報定数を使った属性情報サンプルのグラフ化をしました。
9. Rubyライブラリ「Colorable」とGvizを使ってGraphvizで綺麗なリングを描く
この記事では、Rubyで色を扱うライブラリ「colorable」の紹介と、これをGvizと組合せて作ったカラーリングについて書きました。
10. GraphvizでRubyのロゴは描けますか?
この記事では、Gvizで簡単にRubyのロゴが描けるか挑戦しました。
イマイチでした。
11. Graphvizで作る、私たちの国「日本」の本当の姿かたち
この記事では、@antlaboさんが公開されている隣接市区町村のCSVデータを使って、日本地図の描画に挑戦しました。
ええ、これが私たちの住む日本です。
12. Graphvizで作る、私たちの国「日本」の今度こそ本当の姿かたち
この記事では、先の記事を見て@antlaboさんが全国市町村の位置情報データを公開してくれたので、これに基いて日本地図の描画にリベンジした様子を書いています。
13. これもまた、Graphvizなんです。
この記事は、osage
というレイアウトを使ってカラーサンプルを描画しています。
14. スペースインベーダー、Graphviz侵略ス
この記事は、osage
レイアウトを使ってスペースインベーダーの描画に挑戦した様子を書いています。
ええ、これもGraphvizで書いてるんです。
15. Graphvizレイアウトサンプル
この記事では、名前からはその形が皆目検討がつかないというGraphvizのレイアウトのサンプルを描画しています。
16. Graphvizで作る国旗の類似度世界地図
この記事では、これまた@antlaboさんが公開されている国旗の類似度データを使って、グラフ上で類似度の分布が現れるかに挑戦しています。
17. ピクミンがGraphvizにやって来た!
この記事では、Gvizコマンドの仕様の変更(Thorの利用)の紹介とピクミンの描画に挑戦しています。ピクミンはpng画像データから画素情報を抽出し、間引きを行って各画素をノードとしてGraphvizによる画像化をしています。
18. RubyユニバースをGraphvizで視覚化する
この記事では、Rubyのクラス階層をグラフ化しています。
19. Rubiniusユニバースも視覚化してみる
この記事では、今度はRubiniusのクラス階層をグラフ化しています。
20. JRubyユニバースも視覚化してみる
この記事では、更にJRubyのクラス階層をグラフ化しています。
21. Rubyのソースディレクトリも視覚化してみる
この記事では、Rubyのソースディレクトリのグラフ化に挑戦しています。
22. あなたのプロジェクトを美しく視覚化する
この記事ではディレクトリ構造を簡単にビジュアライズする「dir_friend」というツールの紹介をしています。dir_friendは内部でGvizを使っています。
23. あなたはファイルシステムに美を見るか?
この記事では、dir_friendでテーマを設定できる機能紹介をしています。
24. Graphvizがドローイングソフトになってしまった件について
この記事では、Gvizに追加されたDrawライクなメソッド群の紹介およびそのサンプルについて書いています。
25. Rubyでサインカーブを描いて癒やされる
この記事ではGvizのDraw系メソッドを使ってサインカーブのいろいろなバラエティを描画しています。
26. Rack以外でRackしたいRubyistのためのMatreska
この記事では、アダプタブルなマルチフィルターバンドラー「matreska」の紹介と、これとGvizを組合せてアニメーションGIFを作る例を紹介しています。
27. Graphvizで表そして気になる都知事選2014のゆくえ
この記事では、@otahiさんからのPull Requestから実現したHTML風ラベルの機能紹介と、そのサンプルについて書いています。
28. Gviz(Graphviz ruby wrapper)でクラスタエッジとか無向グラフとか
この記事では、@k1LoWさんからのリクエストで実現したsubgraph(cluster)同士の連結および無向グラフの機能についての紹介をしています。
以上、「Gvizの目次 - Rubyの世界からGraphvizの世界にこんにちは!」でした。ふぅ。
=== Ruby関連電子書籍100円〜で好評発売中! ===
blog comments powered by Disqus