"Diary" インターネットさんへの恩返し

いつもソースコードコピペばかりなので,みなさまへ少しばかりの恩返しを

pydotを使うまでの準備 (苦戦履歴)



スポンサーリンク

言語処理100本ノック 2015の5章で使うグラフのための準備作業。

ひとまず以下が表示されるまで設定したのでメモ。
f:id:azumami:20151124230519j:plain

こういうグラフを作るときは、Dot言語やらを使うのが一般的なようだが、pydotというpythonからdotを呼べるモジュールがあるとのことでやってみた。

pydotインストール

pydotをgitからダウンロードしてインストールしてみる。エラーでこける。

$ git clone https://github.com/erocarrera/pydot.git
$ cd pydot
$ sudo python setup.py install
Traceback (most recent call last):
  File "setup.py", line 8, in <module>
    import pydot
  File "/home/vagrant/pydot/pydot.py", line 22, in <module>
    __version__ = '1.0.%d' % int( __revision__[21:-2] )
ValueError: invalid literal for int() with base 10: ''

pipからインストールしてみる。

$ sudo pip install pydot
Requirement already satisfied (use --upgrade to upgrade): pydot in /usr/local/lib/python2.7/dist-packages
Requirement already satisfied (use --upgrade to upgrade): pyparsing in /usr/lib/python2.7/dist-packages (from pydot)
Requirement already satisfied (use --upgrade to upgrade): setuptools in /usr/local/lib/python2.7/dist-packages/setuptools-18.3.2-py2.7.egg (from pydot)
Cleaning up...

テスト

テストスクリプトを実行してみるも動かない。

テストコード。(pydot.py)
#あとで、このファイル名(pydot.py)自体が、スクリプト内の import pydotでカレントディレクトリのpydot.pyを呼び出す動きになっておりエラーになっていることに気づく。この馬鹿げたミスを理解するまで一週間かかり苦戦する。 

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

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')

実行。

$ sudo python pydot1.py
Traceback (most recent call last):
  File "pydot1.py", line 4, in <module>
    import pydot
  File "/vagrant/100/pydot.py", line 10, in <module>
    g=pydot.graph_from_edges(edges)
AttributeError: 'module' object has no attribute 'graph_from_edges'

コマンドラインからやったら dot_parser が入っていないのがダメらしい。

>>> import pydot
Couldn't import dot_parser, loading of dot files will not be possible.

これしたらうまくいきそう
pydotのdot_parserエラー | CHAZINE.COM

$ sudo cp /usr/local/lib/python2.7/dist-packages/dot_parser.py /usr/local/lib/python2.7/dist-packages/dot_parser.py.org


一分コメントアウトして、以下の文を付け足す。

"""
from pyparsing import __version__ as pyparsing_version

from pyparsing import ( nestedExpr, Literal, CaselessLiteral, Word, Upcase, OneOrMore, ZeroOrMore,
    Forward, NotAny, delimitedList, oneOf, Group, Optional, Combine, alphas, nums,
    restOfLine, cStyleComment, nums, alphanums, printables, empty, quotedString,
    ParseException, ParseResults, CharsNotIn, _noncomma, dblQuotedString, QuotedString, ParserElement )
"""

from pyparsing import ( nestedExpr, Literal, CaselessLiteral, Word, Upcase, OneOrMore, ZeroOrMore,
     Forward, NotAny, delimitedList, oneOf, Group, Optional, Combine, alphas, nums,
     restOfLine, cStyleComment, nums, alphanums, printables, empty, quotedString,
     ParseException, ParseResults, CharsNotIn, dblQuotedString, QuotedString, ParserElement )

_noncomma = "".join( [ c for c in printables if c != "," ] )

テスト出力してみた結果。上手くいった。

>>> 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')
True
>>>

しかしpydot.pyとしたスクリプトはうまくいかない。

$ sudo python pydot.py
Traceback (most recent call last):
  File "pydot.py", line 2, in <module>
    import pydot
  File "/vagrant/pydot.py", line 6, in <module>
    g=pydot.graph_from_edges(edges)
AttributeError: 'module' object has no attribute 'graph_from_edges'

/usr/local/lib/python2.7/dist-packages/pydot.pyの中には、以下のようにちゃんとgraph_from_edgesがある。

def graph_from_edges(edge_list, node_prefix='', directed=False):
    """Creates a basic graph out of an edge list.

    The edge list has to be a list of tuples representing
    the nodes connected by the edge.
    The values can be anything: bool, int, float, str.

    If the graph is undirected by default, it is only
    calculated from one of the symmetric halves of the matrix.
    """

原因は上記に書いた通り pydot.py というファイル名自体が自分を呼び出すというループになっていため。 test.py とかでテストすれば動く。


やっと、課題に取り掛かれる。。。