2510470 ランダム
 ホーム | 日記 | プロフィール 【フォローする】 【ログイン】

傀儡師の館.Python

PR

日記/記事の投稿

カレンダー

キーワードサーチ

▼キーワード検索

カテゴリ

バックナンバー

2020年01月
2019年12月
2019年11月
2019年10月
2019年09月
2019年08月
2019年07月
2019年06月
2019年05月
2019年04月

フリーページ

プロフィール


kugutsushi

サイド自由欄

設定されていません。
2007年11月07日
XML
カテゴリ:Python
グラフ図を書きたくなったので、pydot がどの程度使えるか調べてみる。

こんな図とかこんな図とか Python のプログラムから描けたらいいなと。この図は Graphviz - Graph Visualization Software で描かれたもので、この Python のラッパーとなるのが pydot。pydot のオリジナルの作者のサイト を見ると pydot - Python interface to Graphviz's Dot language(Google code) をメインにするよということなので、そちらを中心に見る。でもドキュメントは pydot (version 0.9.10): Graphviz's dot language Python interface でオリジナルサイトにあったりする。現状、まだ、オリジナルサイトの方が情報が多い。

必要なもの

Windows の場合、標準の Python ではなく、Python Enthought Edition とかインストールしておくと、Graphviz や pyparsing、pydot が最初からインストールされているので楽だったりする。インストールされていない環境の場合は個別にインストールする。残念ながら pydot は easy_install に対応していない。ん、pypi も pydot の URL がまだ dkbza.org(オリジナルのサイト) で Google Code に移行していない。pydot のダウンロードはここから

# easy_install pydot
Searching for pydot
Reading http://cheeseshop.python.org/pypi/pydot/
Reading http://dkbza.org/pydot.html
Reading http://cheeseshop.python.org/pypi/pydot/0.9.10
No local packages or download links found for pydot
error: Could not find suitable distribution
for Requirement.parse('pydot')

なお、注意点としては、Graphviz のバイナリ (fdp, twopi, neato, dot, circo) があるディレクトリをパスに追加しておくこと。そうしないと使えない。Enthought の場合は、\Python24\Enthought\Graphviz\bin が PATH に追加されているはずなので特に問題なし。もし、使えない場合は PATH をチェック。

実際に使ってみる。とりあえず、まずは動くかどうかを
http://dkbza.org/pydot.htmlと同じようにしてテスト。

import pydot

edges=[(1,2), (1,3), (1,4), (3,4)]
g=pydot.graph_from_edges(edges)
g.write_jpeg('graph_from_edges_dot.jpg', prog='dot')

無事に表示される。では日本語を入れるとどうなるだろうかとやってみる。数字ではなく、文字列を入れるとアルファベットは表示されるが、日本語は文字化けしてしまう。

#!/usr/bin/env python
#-*- coding: utf-8 -*-

import pydot

edges=[('root', u'日本語'), ('root', 'Latin'),
('root' , 'English'), ('Latin', 'English')]
g=pydot.graph_from_edges(edges)
g.write_jpeg('graph_from_edges_dot.jpg', prog='dot')

pydot-test02.JPG

さて、文字化けする原因はどこにあるか。とりあえず Graphviz が日本語が通るか見てみる。Graphviz 簡単な使い方 を見ると、

Windows版のdottyで日本語を表示することはできない(ようだ)が、dotから出力する画像ファイルで日本語を出力することは可能。バージョンはGraphviz2.6。以下そのやりかた。

が書かれていた。一つはdotファイルをUTF-8で書いて、フォントの指定をすること。もう一つは、lefty を改造して Shift_JIS に対応したパッチを当てたものを使う方法が書かれている。UTF-8 でいいので、前者を試すことにする。pydot.py の末尾 class Dot の def create を見てみると、

self.write(tmp_name)
stdin, stdout, stderr = os.popen3(self.progs[prog]+' \
-T'+format+' '+tmp_name, 'b')

と、テンポラリファイルに dot ファイルを書き出しておいて、popen3 で Graphviz のプログラムを呼び出してそのファイルを処理させているようなので、書き出すところでフォントの指定を入れてやればよいかな、と思ったら、各クラスをよく見たら、fontpath とか fontname の attribute を持たせられるようになっているので、そこで指定してやればよいか。で、次のようにしてみる。

g=pydot.graph_from_edges(edges)
g.fontname="arialuni.ttf"
g.fontsize=10

ところが、これでは文字化けのまま。原因を探るために、試しに、dot ファイルをまず手で書いてみる。

graph "g" {
node [fontname="arialuni.ttf", fontsize=10]
"root";
"日本語";
"root" -- "日本語";
"ラテン語";
"root" -- "ラテン語";
"英語";
"root" -- "英語";
"ラテン語" -- "英語";
}

test.dot ファイルに上記を入れておいて実行してみる。

dot -Kneato -Tjpg test.dot -o pydotteset01.jpg

pydottest01.jpg

これだと、ちゃんと日本語が表示される。pydot から出力されているファイルを見ると、次のようになっている。node の属性がベタに書き出されていて、ちゃんとリストになっていないからなのかな。

graph G {
fontsize=10;
fontname="arialuni.ttf";
"root";
"日本語";
"root" -- "日本語";
"Latin";
"root" -- "Latin";
"English";
"root" -- "English";
"Latin" -- "English";
}

試しに手書きで、node [fontsize=10, fontname="arialuni.ttf"] と書き換えてやると、日本語が表示できるようになった。ということで node を作って、そこに属性を指定することにした。が、g.add_node でそのノードを追加すると一番最後に追加されてダメなので、pydot.py の class Graph の def add_node の中を書き換えてみるとちゃんと日本語が表示されるようになった。、

- # self.sorted_graph_elements.append(graph_node)
+ if graph_node.name == 'node':
+ self.sorted_graph_elements.insert(0, graph_node)
+ else:
+ self.sorted_graph_elements.append(graph_node)

pydot-test03.JPG

なんだか強引なやり方だが、とりあえず pydot で日本語が出せた。適当なことをやっているので副作用があるかもしれない。というか、ドキュメントちゃんと読んだら、もっとちゃんとした使い方があるのかもしれないが、面倒なのでとりあえず。あとで Google で探してみるかな。まあ、とりあえず日本語が使えることは確認できたのでよしとする。

#!/usr/bin/env python
#-*- coding: utf-8 -*-

import pydot

edges=[(u'私', u'食べる'),
(u'私', u'遊ぶ'),
(u'私' , u'寝る'),
(u'寝る', u'ベッド'),
(u'寝る', u'道端'),
(u'食べる', u'魚'),
(u'食べる', u'米'),
(u'食べる', u'肉'),
(u'遊ぶ', 'Python'),
('Python', 'pydot'),
('pydot', 'pyparse'),
('pydot', 'Graphviz'),
]

n = pydot.Node('node')
n.fontname = "arialuni.ttf"
n.fontsize = 9
n.fontcolor = "blue"

g=pydot.graph_from_edges(edges)
g.add_node(n)
g.write_jpeg('graph_from_edges_dot.jpg', prog='dot')

pydot-test04.JPG


なかのひと







最終更新日  2007年11月07日 16時35分57秒
コメント(3) | コメントを書く
[Python] カテゴリの最新記事

Copyright (c) 1997-2020 Rakuten, Inc. All Rights Reserved.