この記事では、Pythonで木構造のグラフを描画する方法を解説します。
Python で木構造のグラフを描画するには「graphviz」を使います。
graphviz とは、DOT言語というテキストを用いてグラフを表現するためのツールである「Graphviz」を Python で使えるようにしたものです。
それでは、実際にグラフを描画しながら使い方を確認していきましょう!
準備
まずは pip で graphviz をインストールしましょう!
pip install graphviz
Graphviz のインストールも必要です。以下のリンクを参考にインストールしてください。
外部リンクDownload | Graphviz
簡単なグラフの描画
では、簡単なグラフを描画してみましょう!
from graphviz import Digraph
# 有向グラフのインスタンス化
g = Digraph()
# 属性の指定
g.attr('node', shape='circle')
# エッジの追加
g.edge('0', '1', '0~1')
g.edge('0', '2', '0~2')
# 出力
g.view()
上記コードを実行すると以下のような木構造のグラフが表示されます。
それでは、詳しくソースコードを見ていきます。
インポート
有向グラフを生成するには graphviz
の Digraph
クラス を使います。
from graphviz import Digraph
インスタンス化
Digraph
クラス のインスタンスを生成しています。
g = Digraph()
このインスタンスを用いてグラフを描画していきます。
属性の指定
グラフやノード、エッジの属性を指定することができます。このコードでは、ノードの形を円に指定しています。
g.attr('node', shape='circle')
エッジの追加
第一引数から第二引数までの矢印もといノードが生成されます。第三引数ではその矢印のラベルを指定しています。
g.edge('0', '1', '0~1')
g.edge('0', '2', '0~2')
描画
生成したノードや矢印を描画します。
g.view()
属性の変更
属性を指定することで様々な効果を与えることができる。属性を変更するとそれ以降に生成されるオブジェクト全てに影響を及ぼします。
例えば、ノードの形を二重丸に変更したらそれ以降に生成したノードは全て二重丸になります。もちろん、変更することも可能です。
from graphviz import Digraph
# 有向グラフのインスタンス化
g = Digraph(format='png')
g.attr(bgcolor='gray') # グラフの属性の指定(背景色を変更)
g.attr('node', shape='doublecircle') # ノードの属性の指定(形の変更)
g.attr('edge', arrowsize='1.8') # エッジの属性の指定(サイズの変更)
# エッジの追加
g.edge('A', 'B')
# 出力
g.view()
上記コードを実行すると以下のようなグラフが描画される。
ノードなどに直接属性を指定することもできる。
from graphviz import Digraph
# 有向グラフのインスタンス化
g = Digraph()
g.attr('node', color='blue') # ノードの属性の指定(色の変更)
# ノードの追加
g.node('A')
g.node('B', color='red') # 直接属性を指定
# エッジの追加
g.edge('A', 'B')
# 出力
g.view()
変更できる属性については以下を参考にしてください。
グラフの保存
生成したグラフを保存するには、render()
メソッド を使います。
from graphviz import Digraph
# 有向グラフのインスタンス化
g = Digraph()
# エッジの追加
g.edge('A', 'B')
# tree という名前で保存
g.render('tree')
上記コードを実行すると同ディレクトリ内に以下のような「tree.pdf」が生成されます。
画像のフォーマットを変更したい場合は、インスタンス生成時に指定します。
from graphviz import Digraph
# フォーマットの指定
g = Digraph(format='png')
g.edge('A', 'B')
g.render('tree')
まとめ
この記事では、Python で木構造のグラフを描画する方法を解説しました。
graphviz
パッケージを使うことでとても簡単に描画することができましたね。
それでは今回の内容はここまでです。ではまたどこかで〜( ・∀・)ノ