【Python】Graphviz の使い方とキーワードマップを描くコード例【Windows】

グラフビズ (Graphviz) でキーワードマップを描く方法です。

Python から Graphviz を呼び出して作図します。

Graphviz はコマンドラインツールですが、Python から呼び出すためのライブラリ『graphviz』がありました。

それを使った Python コード例を紹介します。

コードは VisualStudioCode で書きました。

『graphviz』でドット言語(DOT言語)のデータを作り、それを Graphviz に渡してキーワードマップを作ります。

スポンサーリンク

Graphviz の使い方

Windows で Graphviz を使う方法です。

  1. グラフビズ(Graphviz)の公式サイトから『Graphviz の本体』をダウンロードして、インストールします。
  2. Windows の環境変数に、binフォルダへのパス『***\Graphviz2.38\bin』を追加します。
  3. Python の pip で『graphviz』をインストールします。
  4. グラフに使うフォントの名前を用意します(とりあえず『MS Gothic』を使います)。
  5. graphviz.Digraph() でドット言語(DOT言語)のデータを作り、dot.render() でグラフ画像を描画&保存します。

以上です。

Graphviz の本体をインストールする

Graphviz の公式サイトから、Windows 用の Graphviz をダウンロードします。

Graphviz – Graph Visualization Software
https://www.graphviz.org/download/

2019年9月の時点で、以下の2種類がありました。

  • インストーラー版の『graphviz-2.38.msi
  • zip版の『graphviz-2.38.zip

自分は、インストーラー版 (.msi) を使っています。

どちらでも、Python ライブラリの graphviz は使えました。

そして、どちらのケースでも、『環境変数への bin フォルダパス追加』が必要でした

インストーラー版を使った場合でも『パスの追加』が必要だった

Graphviz は、インストーラー版を使ってインストールした場合でも、『環境変数への bin フォルダパス追加』が必要でした。

インストーラー版ということで、『パスを通す作業もやってくれるのかな?』と思ったのですが、そこまではしないみたいでした。

自分で環境変数の Path に追加すればOKです。

環境変数に Graphviz の bin フォルダパスを追加する

Graphviz の中にある『bin フォルダへのパス』を、環境変数に追加します。

追加しないと、Python の traceback で、以下のエラーが出ました。

FileNotFoundError: [WinError 2] 指定されたファイルが見つかりません。
graphviz.backend.ExecutableNotFound: failed to execute ['dot', '-Tpng', '-O', 'keyword_map'],
make sure the Graphviz executables are on your systems' PATH

環境変数にパスを追加する方法です。

『コントロールパネル』⇒『システム』⇒『システムの詳細設定』⇒ タブの『詳細設定』⇒『環境変数(N)…』を開きます。

(ユーザー名)のユーザー環境変数の Path』か、『システム環境変数の Path』のどちらかに、bin フォルダパスを追加します。

自分は『(ユーザー名)のユーザー環境変数の Path』に追加しました。

インストーラー版の『graphviz-2.38.msi』を使ってインストールしたので、

C:\Program Files (x86)\Graphviz2.38\bin

を、以下のように追加しました。Windows 7 の画面です。

既存の文字列の後ろにセミコロン『;』をつけて、その後ろに、フォルダパスを追加しています。

Windows 10 の場合は、もっと分かりやすい画面になっていました。

以上です。

『システム環境変数の Path』に追加したときは、以下のような画面になりました。

『システム環境変数の Path』にパスを追加した場合でも、Python ライブラリの graphviz は使えました。

確認方法(コマンドラインで dot -V を実行してみる)

コマンドライン (cmd.exe) を起動して、以下のコマンドを実行します。

これは、Graphviz2.38\bin の中にある dot.exe のバージョンを表示する、というコマンドです。

Graphviz 公式マニュアル
Command-line Invocation

dot -V

実行結果です。

以下のようにバージョンが返れば、Python の graphviz からも Graphviz が使えるようになっています。

dot - graphviz version 2.38.0 (20140413.2041)

一方で、環境変数をうまく設定できていなかったときは、以下のようになりました。

C:\>dot -V
'dot' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。

環境変数の変更は VisualStudioCode の再起動で反映された

環境変数に追加したフォルダパスは、VisualStudioCode を再起動すると反映されました

Windows の再起動や、ログアウト ⇒ 再ログインといった操作は不要でした。

コマンドライン (cmd.exe) を使っていた場合も同様でした。

いったんコマンドラインを閉じて、再度 cmd.exe を開くと、環境変数の変更が反映されました。

(PATH コマンドで『C:\Program Files (x86)\Graphviz2.38\bin』が表示されるようになりました。)

『(ユーザー名)のユーザー環境変数の Path』に追加した場合と、『システム環境変数の Path』に追加した場合を両方試しましたが、どちらも同じふるまいでした。

フォルダパスの追加で、FileNotFoundError や graphviz.backend.ExecutableNotFound といったエラーが出なくなりました。

環境変数からフォルダパスを削除した場合も、VisualStudioCode を再起動すると反映されました

グラフに使うフォントの名前を用意する(MS Gothic など)

graphviz で作る DOT 言語ファイルの中で、日本語フォントを指定すると、日本語が表示できるようになります。

日本語フォントを指定するときの名前ですが、日本語フォントを英語名で指定すると表示できました。

標準の Windows で使えるフォント名のリストは、マイクロソフトの公式サイト(英語)にありました。

Microsoft Typography(マイクロソフト タイポグラフィ)』⇒『Fonts and typefaces(フォント アンド タイプフェイス)』のページに、Windows 7、Windows 8、Windows 8.1、Windows 10 のフォント名がありました。

通常は『MS Gothic』、『MS Mincho』、『Meiryo』、『Yu Gothic』、『Yu Mincho』あたりを使うことになると思います。

Microsoft Office をインストールしたときに追加されるフォントは、載ってないようでした。

ですが、『HGMaruGothicMPRO』といった英語名で指定すれば使えました(HG丸ゴシックM-PRO)。

そのほか、Noto フォントの『NotoSansMonoCJKjp-Regular.otf』インストールして、『Noto Sans Mono CJK JP Regular』というフォント名を指定して使うこともできました。

日本語を含むフォント名を指定すると graphviz でエラーになった

試しに『MS Gothic』を『MS ゴシック』で指定したところ、UnicodeDecodeError が出ました。

Traceback (most recent call last):
  File "c:\***\graphviz_main.py", line 102, in <module>
    main()
  File "c:\***\graphviz_main.py", line 87, in main
    dot.render(
  File "C:\***\Python36\lib\site-packages\graphviz\files.py", line 209, in render
    quiet=quiet)
  File "C:\***\Python36\lib\site-packages\graphviz\backend.py", line 205, in render
    run(cmd, capture_output=True, cwd=cwd, check=True, quiet=quiet)
  File "C:\***\Python36\lib\site-packages\graphviz\backend.py", line 168, in run
    _compat.stderr_write_bytes(err, flush=True)
  File "C:\***\Python36\lib\site-packages\graphviz\_compat.py", line 62, in stderr_write_bytes
    sys.stderr.write(data.decode(encoding))
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x82 in position 56: invalid start byte

この Traceback を見るに、何か Graphviz の本体でエラーが起こって、その標準エラー出力がうまくデコードできなくて UnicodeDecodeError になったようです。

英語名の『MS Gothic』で指定したら、エラーが出ませんでした。

Python ライブラリの graphviz をインストールする

Graphviz と同じ名前の Python ライブラリ『graphviz』をインストールします。

Python の pip でインストールします。

pip install graphviz

Python の graphviz の PyPI のページです。

https://pypi.org/project/graphviz/

Python の graphviz の公式マニュアルです。

Graphviz – graphviz documentation
https://graphviz.readthedocs.io/en/stable/

キーワードマップを描く Python コード例

graphviz でキーワードマップを作るコード例です。

手順は3ステップです。

  1. キーワードリスト」を用意する。
  2. graphvizで「DOT言語のデータ」を作る。
  3. 「DOT言語ファイル」と「グラフ画像」をファイルに保存する。

以上です。

「DOT言語ファイル」が必要ない場合は、2通りの対処法があります。

  • dot.render() の引数に cleanup=True を指定して、自動で削除してもらう。
  • dot.pipe() でグラフ画像のバイナリデータだけを受け取って、Python の open(file, 'wb') でファイルに保存する。

自分は dot.pipe() で画像だけを受け取るアプローチを良く使っています。

graphviz のメソッドには色々な引数がありますが、必要なものだけ指定すればOKでした。

各種メソッドの説明は、graphviz の公式マニュアルの API Reference にありました。

"""Graphvizでキーワードマップを作図するPythonコード例"""

import graphviz

def main():
    # (1/3) 「キーワードリスト」を用意する

    keyword_list = [
        ['グラフビズ'],
        ['graphviz'],
        ['graphviz', 'python'],
        ['graphviz', 'windows'],
        ['graphviz', '日本語'],
        ['graphviz', '使い方'],
        ['graphviz', '使い方', 'windows'],
        ['graphviz', '使い方', 'python'],
        ['graphviz', '使い方', '日本語'],
        ['graphviz', 'python', '日本語'],
        ['graphviz', 'python', 'windows'],
        ['graphviz', 'python', '環境変数'],
        ['graphviz', 'python', 'windows', 'install'],
        ['graphviz', 'python', '色'],
        ['graphviz', 'python', '決定木'],
        ['graphviz', '日本語', '文字化け'],
        ['graphviz', '日本語', 'python'],
        ['graphviz', '日本語', '表示されない'],
        ]


    # (2/3) graphvizで「DOT言語のデータ」を作る

    # DOT言語ファイルのファイル名を決める
    dot_filename = 'keyword_map'

    # DOT言語ファイルと画像の保存フォルダを決める
    datas_dir = r'***\datas'

    # ダイグラフ Digraph のインスタンスを作成
    dot = graphviz.Digraph(
            # name=None,
            comment='Graphvizでキーワードマップを作図する',
            filename=dot_filename, # DOT言語ファイルのファイル名 (ここの名前がグラフ画像のファイル名にも使われる)
            directory=datas_dir, # DOT言語ファイルと画像を保存するフォルダ
            format='png', # グラフの保存形式
            engine='dot',
            # encoding='utf-8',
            # graph_attr=(('fontname', 'MS Gothic'), ),
            # node_attr=(('fontname', 'MS Gothic'), ('shape', 'box'), ('color', 'blue'), ('style', 'rounded')),
            # edge_attr=(('fontname', 'MS Gothic'), ('penwidth', '1.5'), ('color', 'gray')),
            # body=None,
            # strict=False,
            )

    # フォントの名前 (英語名を使えばOK)
    fontname = 'MS Gothic'

    # グラフ フォントを指定する
    dot.attr('graph', fontname=fontname)

    # ノード フォント、枠線の形、枠線の色、枠線のスタイルを指定する
    dot.attr('node', fontname=fontname, shape='box', color='blue', style='rounded')

    # エッジ フォント、矢印の太さ、矢印の色を指定する
    dot.attr('edge', fontname=fontname, penwidth='1.5', color='gray')

    # キーワードを追加する
    for ks in keyword_list:
        # キーワードの数が2個未満のときは、ノードとして追加。
        if len(ks) < 2:
            for k in ks:
                dot.node(k)
        else:
            # そうでなければ、エッジに追加。
            for i in range(len(ks) - 1):
                dot.edge(ks[i], ks[i+1])


    # (3/3) 「DOT言語ファイル」と「グラフ画像」をファイルに保存する
    # 先の graphviz.Digraph() で filename と directory を指定したので、ここは引数なしでOK。
    # もし、graphviz.Digraph() で filename と directory を指定していなければ、ここで指定すればOK。
    dot.render(
        # filename=None,
        # directory=None,
        # view=False,
        # cleanup=False,
        # format=None,
        # renderer=None,
        # formatter=None,
        # quiet=False,
        # quiet_view=False,
        )
    return


if __name__ == '__main__':
    main()

実行結果

dot.render() で、『DOT 言語ファイル (keyword_map)』と『PNG 画像ファイル (keyword_map.png)』ができました。

DOT 言語ファイル (keyword_map)

Python ライブラリの graphviz が生成した、DOT 言語のファイルです。

// Graphvizでキーワードマップを作図する
digraph {
	graph [fontname="MS Gothic"]
	node [color=blue fontname="MS Gothic" shape=box style=rounded]
	edge [color=gray fontname="MS Gothic" penwidth=1.5]
	"グラフビズ"
	graphviz
	graphviz -> python
	graphviz -> windows
	graphviz -> "日本語"
	graphviz -> "使い方"
	graphviz -> "使い方"
	"使い方" -> windows
	graphviz -> "使い方"
	"使い方" -> python
	graphviz -> "使い方"
	"使い方" -> "日本語"
	graphviz -> python
	python -> "日本語"
	graphviz -> python
	python -> windows
	graphviz -> python
	python -> "環境変数"
	graphviz -> python
	python -> windows
	windows -> install
	graphviz -> python
	python -> "色"
	graphviz -> python
	python -> "決定木"
	graphviz -> "日本語"
	"日本語" -> "文字化け"
	graphviz -> "日本語"
	"日本語" -> python
	graphviz -> "日本語"
	"日本語" -> "表示されない"
}

PNG 画像ファイル (keyword_map.png)

Graphviz で描いたキーワードマップのグラフ画像です。

 

タイトルとURLをコピーしました