PythonでGraphvizを使う#

公開日

この記事ではGraphvizをPythonで使う方法を解説します。 Windows環境を例にGraphvizをインストールする手順を示し、Pythonで簡単なグラフを出力する例を示します。

インストール#

GraphvizをPythonで使う場合、Gprahviz本体とPythonライブラリの2つをインストールする必要があります。

Gprahviz本体#

Graphvizの公式サイト (https://graphviz.org/) の"Download"ページから、インストーラをダウンロードします。 ここでは、記事執筆時点の最新版 v12.1.2の64ビット版"graphviz-12.1.2 (64-bit) EXE installer"をダウンロードします。

graphviz-install-page

次に、インストーラを実行してGraphviz本体をインストールします。 このとき、Graphvizにパスを通します。 ここでは"Add Graphviz to the system PATH for current user"を選択します。

graphviz-installer

インストール完了後、PowerShellを起動してdot -Vコマンドを実行します。 Graphvizのバージョンが表示されれば、インストールとパスの追加に成功しています。

> dot -V
dot - graphviz version 12.1.2 (20240928.0832)

Pythonライブラリ#

次に、以下のコマンドでPythonライブラリのGraphvizをインストールします。

pip install graphviz

以上でインストールは完了です。

簡単なグラフの作成#

PythonでGraphvixを使って簡単なグラフを作成する例を以下に示します。

from graphviz import Digraph

graph = Digraph()

graph.node("node1")
graph.node("node2")

graph.edge("node1", "node2")

graph
../_images/b1cf84cd17092e95775d13b872f625574f34179ee01a42148fc4bbf9e5673bd3.svg

上記のコードについて解説します。

from graphviz import Digraph

graphvizのライブラリからDigraphをインポートします。Digraphは矢印付きのグラフ(有向グラフ、Directed graph)のことです。 矢印がないグラフの場合、Graphをインポートします。

次に、以下でグラフの構造を定義します。 node()メソッドでノード(点)を1つずつ定義し、edge()メソッドでエッジ(線)を定義します。

graph = Digraph()

graph.node("node1")
graph.node("node2")

graph.edge("node1", "node2")

Jupyter環境ではgraphと記述するだけで描画できます。

なお、描画することをコードで明示する場合、以下のようにgraph.render()メソッドとIPython.display.Image()を組み合わせる方法もあります。 graph.render()メソッドを実行するとグラフの画像が保存され、戻り値として保存したファイルのパスが返ります(format引数でファイル形式を指定します)。 さらに、IPython.display.Image()は指定されたパスのファイルを描画します。

from graphviz import Digraph
from IPython.display import Image

graph = Digraph()

graph.node("node1")
graph.node("node2")

graph.edge("node1", "node2")

Image(graph.render(format="png"))
../_images/0c05e4cf40c48a3d60a61f8abae506e44a269d94e6708a1b32b8205489470d4d.png

グラフの保存#

Pythonライブラリのgraphvizでは、グラフを画像ファイルとテキストファイル(DOT形式)で保存できます。

画像ファイル#

グラフを画像ファイルで保存する場合、render()メソッドを使用します。 render()メソッドのデフォルトの動作では、DOT言語のソースファイルと画像ファイルの2つが出力されます。 このメソッドの主なオプションを示します。

render(filename=None, directory=None, view=False, cleanup=False, format=None)

オプション

説明

filename

str

保存するファイル名(拡張子を除く)

directory

str

保存するディレクトリ

view

bool

Trueの場合、画像ビューワで開く

cleanup

bool

Trueの場合、DOT言語のソースファイルを削除する

format

str

保存する画像の形式

formatオプションにはsvg, png, pdfなどが指定できます。 指定可能なフォーマット一覧はgraphviz.FORMATSで表示できます。

from pprint import pprint
import graphviz

pprint(graphviz.FORMATS, compact=True)
{'bmp', 'canon', 'cgimage', 'cmap', 'cmapx', 'cmapx_np', 'dot', 'dot_json',
 'eps', 'exr', 'fig', 'gd', 'gd2', 'gif', 'gtk', 'gv', 'ico', 'imap', 'imap_np',
 'ismap', 'jp2', 'jpe', 'jpeg', 'jpg', 'json', 'json0', 'pct', 'pdf', 'pic',
 'pict', 'plain', 'plain-ext', 'png', 'pov', 'ps', 'ps2', 'psd', 'sgi', 'svg',
 'svgz', 'tga', 'tif', 'tiff', 'tk', 'vml', 'vmlz', 'vrml', 'wbmp', 'webp',
 'x11', 'xdot', 'xdot1.2', 'xdot1.4', 'xdot_json', 'xlib'}

なお、アルファベット順にソートしたい場合、Pythonの組込み関数のsorted()を使えます。

pprint(sorted(graphviz.FORMATS), compact=True)
['bmp', 'canon', 'cgimage', 'cmap', 'cmapx', 'cmapx_np', 'dot', 'dot_json',
 'eps', 'exr', 'fig', 'gd', 'gd2', 'gif', 'gtk', 'gv', 'ico', 'imap', 'imap_np',
 'ismap', 'jp2', 'jpe', 'jpeg', 'jpg', 'json', 'json0', 'pct', 'pdf', 'pic',
 'pict', 'plain', 'plain-ext', 'png', 'pov', 'ps', 'ps2', 'psd', 'sgi', 'svg',
 'svgz', 'tga', 'tif', 'tiff', 'tk', 'vml', 'vmlz', 'vrml', 'wbmp', 'webp',
 'x11', 'xdot', 'xdot1.2', 'xdot1.4', 'xdot_json', 'xlib']

また、render()メソッドの戻り値は保存された画像ファイル名となります。

例:以下のオプションで実行すると、画像my_graph.pngとソースファイルmy_graphが保存されます。

graph.render("my_graph", format="png")
'my_graph.png'

DOTソースファイル#

DOT形式で保存するメソッドは用意されていませんが、以下のようにsource属性を使うとテキスト形式で出力できます。

print(graph.source)
digraph {
	node1
	node2
	node1 -> node2
}

そのため、Pythonのopen関数を使って保存できます。 以下に例を示します。

with open("my_graph.dot", mode="w") as f:
    f.write(graph.source)