Graphvizとは、AT&T研究所の作ったグラフ描画ソフトである。
ここでのグラフとは棒グラフのグラフではなく、ソーシャルグラフとかのグラフである。
点(ノード)と線(エッジ)で表されるもので、例えば、何らかの状態遷移や、路線図や、ネットワークなどの「関係」の表現に使われる。
もともとオイラーの一筆書きのような経路探索の分野があって、それを視覚的に表現するためのツールとしてこういったソフトがある(たぶん)。
そんな分野はとても手に負えない。
しかし、グラフ描画に注目するだけでも、とても面白いんである。
例えば、ふだん利用する路線の、各駅の関係と乗降数をグラフに書いてみるだけでも、表で見たときは比べ物にならないくらいのインパクトがある。
これは、京浜急行の駅の繋がりと乗降者数をグラフにしてみたもの。
隣り合う駅は繋ぐし、特急などで途中の駅をすっ飛ばす場合も繋ぐ。
乗降者数に応じて駅の大きさを変えてみた。
(何気なく作ったら一辺が10,000ピクセルを超える巨大画像になったので泣く泣く縮小した。)
そういったわけで、この記事では(Python経由で)graphvizのグラフ描画についてまとめた。
以下、特に指定のないかぎり、グラフと記載があれば、それは上記の意味でのグラフである。
Graphvizについて
手っ取り早くどんなグラフが描けるのかを知りたければこちらのサンプルグラフなどを。
関連のwebsiteは以下のとおり。
Graphviz(公式) http://www.graphviz.org/
Graphviz(wiki) http://ja.wikipedia.org/wiki/Graphviz
Graphvizでは、DOTという形式でグラフを描画する。
しかしDOT形式をそのまま扱うのはちょっと難しい。
そこで他の言語を通して使う。
具体的にはpygraphviz。
PyGraphvizはGraphvizのpythonインタフェースである。
PyGraphvizのインストール
FreeBSD, OS Xでのインストールは確認済みである。
しかし意外や意外、WindowsのActivePythonではPyGraphvizをインストールできない。PyPMにないのである。
素のPythonなら出来るのかもしれないが。
しかし、Graphviz単体ならインストールできる。DOT形式のファイル(以降、DOTファイル)を別マシンからもらえば、WIndows上でもグラフ描画は可能。
FreeBSDでのインストール
portsでもpkgでも、pygraphvizで探せば出てくるのでそれをインストールすればよい。
以下はpkgでの例。
gccを連れてきてダウロードサイズが100MBを超えた。驚いた。
ついでnumpyも入れた。
$ pkg search graphviz
graphviz-2.34.0
py27-graphviz-1.1_1
rubygem-graphviz-1.0.9
trac-graphviz-0.7.4_6
$ sudo pkg install py27-numpy py27-graphviz
Updating repository catalogue
The following 12 packages will be installed:
Installing mpc: 1.0.1
Installing gcc-ecj: 4.5
Installing binutils: 2.23.2
Installing py27-nose: 1.3.0
Installing libgd: 2.1.0_1,1
Installing gcc: 4.6.4
Installing graphviz: 2.34.0
Installing blas: 3.4.2_1
Installing py27-graphviz: 1.1_1
Installing lapack: 3.4.2_1
Installing suitesparse: 4.0.2_2
Installing py27-numpy: 1.7.0_2,1
The installation will require 685 MB more space
110 MB to be downloaded
OS Xでのインストール
graphvizをインストールし、そのあとPython上でpygraphvizをインストールすればよろし。
以下の例ではbrewでgraphvizを、そのあとpipでpygraphvizをインストールしている。
$ brew install graphviz
==> Downloading http://www.graphviz.org/pub/graphviz/stable/SOURCES/graphviz-2.3
######################################################################## 100.0%
==> Downloading patches
<snip>
==> make install
/usr/local/Cellar/graphviz/2.30.1: 462 files, 10M, built in 3.1 minutes
$
$ pip install pygraphviz
Downloading/unpacking pygraphviz
Using download cache from /Users/xxx/.pip/cache/https%3A%2F%2Fpypi.python.org%2Fpackages%2Fsource%2Fp%2Fpygraphviz%2Fpygraphviz-1.2.tar.gz
Running setup.py egg_info for package pygraphviz
Trying pkg-config
library_path=/usr/local/Cellar/graphviz/2.30.1/lib
include_path=/usr/local/Cellar/graphviz/2.30.1/include/graphviz
<snip>
no previously-included directories found matching 'doc/build'
Successfully installed pygraphviz
Cleaning up...
$
Windowsでのインストール(graphvizだけ)
WindowsのActivePythonではpygraphvizが使えない。
素のgraphvizをインストールする。
以下あたりからダウンロードする。
http://www.graphviz.org/Download_windows.php
インストーラがよければmsiを、レジストリを汚したくないならzipをダウンロード。
zipは展開するとreleaseというフォルダが出来る。
リネームしてどこにでも置けばよい。
実行ファイルはbinの下にある。
必要ならパスを通しておく。
実際に使う実行ファイルはdot、circo、neatoあたりでしょう。
pygraphvizインストールの確認
pygraphvizをimportしてみてエラーの出ないことを確認しておこう。
たとえばIDLEで。
Python 2.7.5 (default, Oct 17 2013, 07:35:17)
[GCC 4.2.1 Compatible FreeBSD Clang 3.3 (tags/RELEASE_33/final 183502)] on freebsd10
Type "copyright", "credits" or "license()" for more information.
>>> import pygraphviz
>>>
PyGraphvizを使ってみよう。
基本はここのチュートリアルに沿えばよい。
http://networkx.lanl.gov/pygraphviz/tutorial.html
pygraphvizをimportし、AGraphクラスを作る。
import pygraphviz as pgv
G = pgv.AGraph()
ノードの追加
G.add_node('a')
G.add_node('b')
エッジの追加
G.add_edge('c','d')
G.add_edge('e','f')
そして描画。
layoutを指示すると各ノード、エッジの配置がなされ、drawで画像に書き込める。
G.layout()
G.draw('sample01.png')
dotファイルを書き出すには。
G.write("sample01.dot")
サンプルスクリプト
以下、サンプルスクリプトとその結果つくられるグラフを列挙する。
先述の通りWindowsではpygraphvizが使えない。
Windowsでグラフを描こうとするなら、MacやFreeBSD他、pygraphvizで生成しておいたdotをWindows上のgraphvizで読みこむしかない。
その方法は最後に触れる。
サンプル1
#!/bin/env python
import pygraphviz as pgv
G = pgv.AGraph()
G.add_node('a')
G.add_node('b')
G.add_edge('c','d')
G.add_edge('e','f')
G.layout()
G.draw('sample01.png')
サンプル2
ノードの追加は、リストでまとめてできる。
#!/bin/env python
import pygraphviz as pgv
G = pgv.AGraph()
nodelist = ['g','h','i']
G.add_nodes_from(nodelist)
G.add_edge('c','d')
G.add_edge('e','f')
G.layout()
G.draw('sample02.png')
サンプル3
同じエッジを二回追加しても変わらない。
#!/bin/env python
import pygraphviz as pgv
G = pgv.AGraph()
nodelist = ['g','h','i']
G.add_nodes_from(nodelist)
G.add_edge('h','i')
G.add_edge('h','i')
G.layout()
G.draw('sample03.png')
サンプル4
しかし、最初のクラス作成時にstrict=Falseと指定すれば。
#!/bin/env python
import pygraphviz as pgv
G = pgv.AGraph(strict=False)
nodelist = ['g','h','i']
G.add_nodes_from(nodelist)
G.add_edge('h','i')
G.add_edge('h','i')
G.layout()
G.draw('sample04.png')
二本になる。
サンプル5
さらにdirectを指定すれば。
#!/bin/env python
import pygraphviz as pgv
G = pgv.AGraph(strict=False, directed=True)
nodelist = ['g','h','i']
G.add_nodes_from(nodelist)
G.add_edge('h','i')
G.add_edge('h','i')
G.layout()
G.draw('sample05.png')
矢印になる。
サンプル6
ここまでは殺風景であったが、色だって形だって変更できる。
#!/bin/env python
import pygraphviz as pgv
G = pgv.AGraph(strict=False, directed=True)
nodelist = ['g','h','i']
G.add_nodes_from(nodelist)
G.add_edge('h','i')
G.add_edge('h','i')
G.layout()
G.draw('sample05.png')
参考
ここから先は、以下を参考にして各自素敵なグラフを作ってくれたまえ。
https://github.com/pygraphviz/pygraphviz/blob/master/examples/miles.py
pygraphviz attrの一覧
http://www.graphviz.org/doc/info/attrs.html
Windowsでdotからグラフを描画する。
インストールしたdot, circo, neatoのいずれかに、-Tで出力形式を、-oで出力ファイル名を指定したうえで、dotファイルを与えればよい。
dot -Tpng -o filename.png filename.dot
circo -Tpng -o filename.png filename.dot
neato -Tpng -o filename.png filename.dot