技術メモ

役に立てる技術的な何か、時々自分用の覚書。幅広く色々なことに興味があります。

pythonでgraphvizの使い方(美しいツリー構造や状態遷移図の描画)

pythonで美しいグラフ構造を書くためのツール。

pythonでグラフ構造を書くといえば、今有名なのはnetworkxだろう。
でもnetworkxは描画には特化していない。どちらかというと分析に使うツールだ。
特に、状態遷移図や木構造を書くのには向いていない。
そこで登場するのがgraphviz
もともとgraphvizは独立したツールとして存在するが、pythonでラッパーが用意されている。

インストール

まずgraphvizそのもののダウンロードが必要。
Download | Graphviz
そしてライブラリをインストール

pip install graphviz

簡単な使い方

from graphviz import Digraph

G = Digraph(format="png")
G.attr("node", shape="square", style="filled")
G.edge("start","state1",label="0.8")
G.edge("start","state2",label="0.2")
G.edge("state1","state1",label="0.5")
G.edge("state2","state2", label="0.8")
G.edge("state1","state2",label="0.5")
G.edge("state2","end",label="0.2")
G.edge("end","count",label="1.0")
G.edge("count","start",label="1.0")
G.node("start", shape="circle", color="pink")
G.render("graphs")


有向グラフを書きたい時はDigraph、無向グラフを書きたい時はGraphを使用する。
基本的な流れは

  1. Digraph(Graph)で空のグラフを作る。画像として保存したい場合formatで保存形式を決められる,png,pdf,など。
  2. attr()で追加するノードの形などのスタイルを決める
  3. edge()でエッジを追加していく。この時、存在しないノードは自動的に追加される。
  4. 必要であればnode()でノードを追加したり、ラベル(表示名)を変更したりできる。
  5. render()で画像として保存。filenameでファイル名を指定

もちろんこんな木構造のグラフも書ける。

from graphviz import Digraph

G = Digraph(format="png")
G.attr("node", shape="circle")
edges = [(0, 1), (0, 95), (1, 2), (1, 4), (1, 94), (2, 3), (4, 5), (4, 92), (5, 6),
(6, 7), (6, 79), (6, 90), (6, 91), (7, 8), (7, 34), (7, 76), (7, 78), (8, 9), (8, 10), (8, 11),
(11, 12), (12, 13), (12, 28), (12, 29), (13, 14), (13, 21), (13, 25), (13, 26), (14, 15), (14, 17), (14, 18), (14, 20),
(15, 16), (18, 19), (21, 22), (21, 24), (22, 23), (26, 27), (29, 30), (30, 31), (31, 32), (31, 33),
(34, 35), (34, 70), (34, 71), (34, 72), (35, 36), (35, 37), (35, 56), (35, 64), (37, 38), (37, 53), (37, 55),
(38, 39), (39, 40), (40, 41), (40, 44), (40, 47), (40, 51), (40, 52), (41, 42), (42, 43), (44, 45), (44, 46),
(47, 48), (48, 49), (49, 50), (53, 54), (56, 57), (57, 58), (57, 59), (59, 60), (60, 61), (60, 62), (60, 63),
(64, 65), (64, 66), (66, 67), (66, 69), (67, 68), (72, 73), (73, 74), (74, 75), (76, 77), (79, 80), (80, 81), (80, 87),
(81, 82), (81, 86), (82, 83), (82, 84), (82, 85), (87, 88), (88, 89), (92, 93), (95, 96), (95, 98), (96, 97),
(98, 99), (98, 100), (98, 101), (101, 102), (102, 103), (103, 104), (103, 105), (105, 106), (105, 107), (105, 108)]
for i,j in edges:
    G.edge(str(i), str(j))
G.render("tree")


公式サイト

色を付けたり形を変えたり枠を囲ったり、やろうと思えば結構自由度が高い。
一番はやっぱり公式のリファレンスを見ることだろう。
User Guide — graphviz 0.20.1 documentation
Examples — graphviz 0.20.1 documentation
公式の例に従えばこんな綺麗なグラフも描ける。

それではよいグラフ描画ライフを!


関連記事: