事情があって、Pythonで使えるグラフ描画ツールを探しました。いくつか候補があるのですが、NetworkX(http://networkx.lanl.gov/)が良さそうに思えました。
NetworkXは、グラフ描画が主たる目的ではなくて、グラフの操作や解析のためのライブラリです。描画バックエンドは現在 matplotlib, pygraphviz, pydot の3種類をサポートしています(http://networkx.lanl.gov/reference/drawing.html)。PyGrphviz(http://networkx.lanl.gov/pygraphviz/)はNetworkXと同じ開発コミュニティによるもので、NetworkXと類似のAPIを提供してます。描画はPyGraphvizを使おうかな、と。
PyGraphviz is a Python interface to the Graphviz graph layout and visualization package.
PyGraphviz is independent from NetworkX but provides a similar programming interface.PyGraphvizは、グラフのレイアウト・可視化パッケージであるGraphvizに対するPythonインターフェースです。
PyGraphvizは、NetworkXと独立ではありますが、類似のプログラミングインターフェースを提供しています。
Windowsで使うおうと思ったのですが、FAQ(http://networkx.lanl.gov/pygraphviz/reference/faq.html)によると:
We don’t have Windows development machines but would like to have pygraphviz work on all platforms. If you have success with Windows or would be willing to help test and distribute a Windows installer please drop us a note.
私たちはWindows開発マシンを持ってません。でも、pygraphvizがすべてのプラットフォームで動くだろうと思っています。Windowsでうまくいった方、あるいはWindowsインストーラーの配布やテストに協力してくれる方はご連絡ください。
ウーン、大丈夫かな? まーやってみましょう。
内容:
Graphvizのインストール
まずは、Graphviz(http://www.graphviz.org/)をインストールしておきます。ダウンロードは http://www.graphviz.org/Download_windows.php から。Windows用のインストーラー graphviz-2.28.0.msi があります。
デフォルトだと、C:\Program Files\Graphviz 2.28\ にインストールされますが、空白を含むパスがトラブルに繋がるケースがままあったので、僕は C:\Installed\Graphviz-2.28\ にインストール先を変えました。
Path環境変数の設定が必要かもしれません(そのツールをすぐ後に記述)。コマンドラインからdotとかdottyコマンドが動くようになればOKです。
Graphvizのファイル形式はDOT形式と呼ばれていますが、share/graphviz/graphs/ の下のサンプルを見ると、.dot よりは .gv という拡張子がよく使われているんですね。ヘー。
オマケ:環境変数の設定ツール
新しいソフトウェアをインスールすると、環境変数、特にPathを書き換える必要が多いですね。Windowsでは、コントロールパネルから環境変数を設定できますが、あれは使いにくい! Rapid Environment Editor(http://www.rapidee.com/en/about)てのがけっこう便利です。
パスが不正になってしまう書き間違いを指摘してくれるのがありがたい。UIの言語として日本語もサポートしています。おすすめ。
easy_installでインストール -- 失敗
http://networkx.lanl.gov/pygraphviz/install.html によると、easy_install pygraphviz とするのが一番簡単そうです。
easy_installはPythonのパッケージマネージャー/自動インストールツールですが、なぜかPython自体には含まれていません。インストールツールのインストールが必要になってしまうわけです。http://pypi.python.org/pypi/setuptools#files あたりから適当なファイルをダウンロードします。
easy_installを含むsetuptoolsのインストールは、Windowsインストーラーがあるんで特に問題はないでしょう。で、easy_install pygraphviz としてみたのですが、次のようなエラーメッセージで失敗します。
running build_ext building 'pygraphviz._graphviz' extension error: Unable to find vcvarsall.bat
自動インストールはあきらめ、事情を調べるために、http://networkx.lanl.gov/download/pygraphviz/ から pygraphviz-1.1.tar.gz をダウンロードしました。
MinGWでコンパイルできるようにする
PyGraphvizには、graphviz_wrap.c というC言語のソースが含まれ、これのコンパイルで失敗しているようです。
Pythonのdistutilsのなかで、MSVCを起動しようとしてるようです。MSVCは入れてないし、入れるのも面倒なので、既に入っているMinGWでなんとかならないでしょうか。
"Building Python extensions for Windows with only free tools" April 19, 2007 (http://boodebr.org/main/python/build-windows-extensions)によると、MinGWでも出来そうです。そのためには、次のように <Pythonのディレクトリ>\lib\distutils\distutils.cfg というファイルを作ります。
[build] compiler = mingw32
python .\setup.py build としてみると:
The current setting of library_path and include_path is: library_path=None include_path=None Traceback (most recent call last): File ".\setup.py", line 93, in <module> raise OSError,"Error locating graphviz." OSError: Error locating graphviz.
ありゃダメだ。library_pathとinclude_pathの設定が必要そうなので、setup.py を編集しました。
library_path='c:/Installed/Graphviz-2.28/lib/release/lib' include_path='c:/Installed/Graphviz-2.28/include/graphviz'
これでいいだろう。
C:\Installed\MinGW\bin\gcc.exe -mno-cygwin -mdll -O -Wall "-Ic:/Installed/Graphviz 2.28/include/graphviz" -IC:\Installed\Python26\include -IC:\Installed\Python26\PC -c pygraphviz/graphviz_wrap.c -o build\temp.win32-2.6\Release\pygraphviz\graphviz_wrap.o pygraphviz/graphviz_wrap.c: In function `agattr_label': pygraphviz/graphviz_wrap.c:2855: warning: return makes integer from pointer without a cast
おー、なんかコンパイルしているようだ。
writing build\temp.win32-2.6\Release\pygraphviz\_graphviz.def Traceback (most recent call last): File ".\setup.py", line 146, in <module> package_data = package_data File "C:\Installed\Python26\lib\distutils\core.py", line 152, in setup dist.run_commands() File "C:\Installed\Python26\lib\distutils\dist.py", line 975, in run_commands self.run_command(cmd) File "C:\Installed\Python26\lib\distutils\dist.py", line 995, in run_command cmd_obj.run() File "C:\Installed\Python26\lib\distutils\command\install.py", line 577, in run self.run_command('build') File "C:\Installed\Python26\lib\distutils\cmd.py", line 333, in run_command self.distribution.run_command(command) File "C:\Installed\Python26\lib\distutils\dist.py", line 995, in run_command cmd_obj.run() File "C:\Installed\Python26\lib\distutils\command\build.py", line 134, in run self.run_command(cmd_name) File "C:\Installed\Python26\lib\distutils\cmd.py", line 333, in run_command self.distribution.run_command(command) File "C:\Installed\Python26\lib\distutils\dist.py", line 995, in run_command cmd_obj.run() File "C:\Installed\Python26\lib\distutils\command\build_ext.py", line 340, in run self.build_extensions() File "C:\Installed\Python26\lib\distutils\command\build_ext.py", line 449, in build_extensions self.build_extension(ext) File "C:\Installed\Python26\lib\distutils\command\build_ext.py", line 531, in build_extension target_lang=language) File "C:\Installed\Python26\lib\distutils\ccompiler.py", line 769, in link_shared_object extra_preargs, extra_postargs, build_temp, target_lang) File "C:\Installed\Python26\lib\distutils\cygwinccompiler.py", line 260, in link target_lang) File "C:\Installed\Python26\lib\distutils\unixccompiler.py", line 218, in link libraries) File "C:\Installed\Python26\lib\distutils\ccompiler.py", line 1166, in gen_lib_options opt = compiler.runtime_library_dir_option (dir) File "C:\Installed\Python26\lib\distutils\unixccompiler.py", line 285, in runtime_library_dir_option compiler = os.path.basename(sysconfig.get_config_var("CC")) File "C:\Installed\Python26\lib\ntpath.py", line 198, in basename return split(p)[1] File "C:\Installed\Python26\lib\ntpath.py", line 170, in split d, p = splitdrive(p) File "C:\Installed\Python26\lib\ntpath.py", line 125, in splitdrive if p[1:2] == ':': TypeError: 'NoneType' object is unsubscriptable
ガーン、失敗した。
最後はその場しのぎの対処で
失敗の原因を追いかけてみると、/lib/distutils/unixcompiler.py というファイルの次の行に問題があるようです。
compiler = os.path.basename(sysconfig.get_config_var("CC"))
さらに、lib/distutils/sysconfig.py を見ると、sysconfig.get_config_var は、Windowsで "CC" の値を返すようにななっていません。Windowsプラットフォーム用に初期化をする _init_nt() 関数をその場限りかつ強引に書き換えてしまいました。
def _init_nt(): """Initialize the module as appropriate for NT""" # ... # 省略 # g['CC'] = "gcc.exe" # ここに強引に挿入 global _config_vars _config_vars = g
ひどい対処ではありますが、これでコンパイルはうまくいきます。python .\setup.py install とすれば、PyGraphvizがインスールされます。
チュートリアル(http://networkx.lanl.gov/pygraphviz/tutorial.html)にあったサンプルは実行できたので、これでWindows上でもPyGraphvizが使えるようになりました。息切れしちゃったので、グラフの描き方とかはまたいずれ。