Python から Graphviz を使う( pydot を日本語で出力)(3) からの続き。
pydot は
隣接行列 (adjacency matrix) (Wikipedia) からグラフを一発で描くことができるので、それを試してみる。例は Wikipedia にあるものをまず使ってみる。
まずは隣接行列を Python のリストとして用意する。
matrix = [[0, 1, 0, 0, 1, 0],
[1, 0, 1, 0, 1, 0],
[0, 1, 0, 1, 0, 0],
[0, 0, 1, 0, 1, 1],
[1, 1, 0, 1, 0, 0],
[0, 0, 0, 1, 0, 0]]
あるノードと隣接している(リンクがある=エッジを描く)ノードに 1、隣接していなければ 0 を付けていったもので、上記の隣接行列を言葉で表し直すと、次のようになる。
1番のノードと隣接しているのは、2番、5番。
2番のノードと隣接しているのは、1番、3番、5番。
3番のノードと隣接しているのは、2番、4番。
4番のノードと隣接しているのは、3番、5番、6番。
5番のノードと隣接しているのは、1番、2番、4番。
6番のノードと隣接しているのは、4番。
pydot で隣接行列からグラフを描く方法
pydot を使って隣接行列からグラフを生成するプログラムは下のようになる。とりあえず、dot と neato の2通りで出力してみる。
import pydot
# 隣接行列のデータ
matrix = [[0, 1, 0, 0, 1, 0],
[1, 0, 1, 0, 1, 0],
[0, 1, 0, 1, 0, 0],
[0, 0, 1, 0, 1, 1],
[1, 1, 0, 1, 0, 0],
[0, 0, 0, 1, 0, 0]]
# 隣接行列からグラフを生成する
g=pydot.graph_from_adjacency_matrix(matrix)
# グラフを出力、2通り出力してみる
g.write_png('a_matrix01.png')
g.write_png('a_matrix02.png', prog='neato')
a_matrix01.png
a_matrix02.png
隣接行列のリストを渡してやるだけでよいのでとっても楽に描ける。
1,2,3,4,5,6 というノード番号ではなく、何かの文字列に変えたいと思った。次のようにしたらできた。
# 表示用のラベルを用意する。
node_label = {'1':'First', '2':'Second', '3':'Third',
'4':'Forth', '5':'Fifth', '6':'Sixth'}
# ノードを取り出す
nodes = g.get_node_list()
# ノードごとにラベルを設定する
for n in nodes:
n.set_label(node_label[n.name])
# ファイルに出力する
g.write_png('a_matrix03.png', prog='neato')
ということでラベルを後から付けてやれば、文字を入れることができた。さらに日本語を入れたらどうか試してみる。ここでは、前と同じように属性を付けたノードを先頭に挿入してみる。
node_label = {'1':'一番目', '2':'二番目', '3':'三番目',
'4':'四番目', '5':'五番目', '6':'六番目'}
# ノードを取り出す
nodes = g.get_node_list()
# ノードごとにラベルを設定する
for n in nodes:
n.set_label(node_label[n.name])
# 属性を設定するノードを作って先頭に追加する
n = pydot.Node('node')
n.fontname = "arialuni.ttf"
g.sorted_graph_elements.insert(0, n)
# ファイルに出力する
g.write_png('a_matrix04.png', prog='neato')
ということで、隣接行列から作成したグラフに日本語のラベルを付けて表示することもできた。