焼肉on寿司onピザ

プログラミングとか、かっこいい音楽とかの話を

【Python3】【Windows10】状態遷移パッケージtransitionsをAnaconda, pygrapgvizなしで使用する方法

はじめに

pythonの状態遷移管理パッケージtransitionsは、簡単に状態遷移を記述できる非常に便利なパッケージです。以下のページで日本語で非常に詳しくまとめてくださっています。(ありがたい)
qiita.com

基本的に、ここに書いてある通りに試していけばいいのですが、ライブラリのインストールで壁にぶち当たったので書いておきます。

環境

Windows10
Python3.7.4
Anacondaは非導入
【追記】transitions 0.7.1

発生した問題

Pygraphvizが入らねえ
Anaconda入れたくねえ

発生した経緯

今回の問題の原因は、状態遷移を表示する画像パッケージのインストールで問題が発生しているようです。transitionの開設サイトに書いてある通り(conda無しver)に進めると

pip install git+https://github.com/pytransitions/transitions.git@dev-graphviz

このコマンド試すとエラーが...
gitから直接ダウンロードしてsetup.pyしてもダメでした
結局原因がわからず、pygraphvizをどうにか入れる方法を探したのですが...

「Anacondaを使わずに」pygraphvizを導入する方法の一つで、以下も試しましたが、うまくできず...(雑魚)
hytmachineworks.hatenablog.com

解決方法

transitions解説サイトをよく読むと次のような記述が...

※ちなみに次期Versionの0.70ではPyGraphvizは使用しない方向になっているので、Version0.69までの対応となる見込みです。(「Windowsの場合」参照のこと)

な~~~んだ、じゃあpygraphvizを使わないtransitionsのコードを書けばええのか~~
というオチでした
ちゃんと読めよ

てことで、pygraphvizを使わないでtransitionsを使う方法をご紹介します

pygraphvizを使用せずにtransitionsを使う

日本語でこの解説してるページがなかったので書いておきますv
transitionsのソースが載ってるgithubと先述の日本語解説サイトを参考にしています
github.com

インストール

まずは最新版のtransitionsとgraphvizをインストールしてください
graphvizは公式サイトから、Stable 2.38 Windows install packagesをインストールしてからpipしましょう。その後、パスも/binまで通して再起動
https://graphviz.gitlab.io/download/

pip install transitions
pip install graphviz

dotが通っているか確認、バージョンが出てきたら成功です

dot -V

出力例

dot - graphviz version 2.38.0 (20140413.2041)

transitionsで状態遷移図の出力

例の開設サイトに載っているwindows向けのコードですが、実行すると
"Exception: AGraph diagram requires pygraphviz"というエラーが発生します
pygraphvizを要求してくるわけですね

import graphviz
from IPython.display import Image, display
from transitions.extensions import GraphMachine

states = ['A', 'B', 'C']        #状態の定義

class Matter(object):
    def __init__(self, filename=None):
        self.output = filename

    def action_output_graph(self, *args, **kwargs):
        dg = model.get_graph(*args, **kwargs).generate()
        if isinstance(self.output, str):
            graphviz.Source(dg, filename=self.output, format='png').render(cleanup=True) 
        else:
            display(Image(dg.pipe(format='png'))) 

model = Matter('test')         #ファイル出力する場合は、Matter('test')にする。
machine = GraphMachine(model=model, states=states, initial='A', 
                       auto_transitions=False, ordered_transitions=True,
                       title='', show_auto_transitions=False, show_conditions=False, 
                       finalize_event='action_output_graph')    

model.action_output_graph()     #初回のみ手動実施


こちらを次のように書き換えるとうまく実行され、同じフォルダに状態遷移の画像が出力されます

変更後のコード

import graphviz
from IPython.display import Image, display
from transitions.extensions import GraphMachine

states = ['A', 'B', 'C']        #状態の定義

class Matter(object):
    def __init__(self, filename=None):
        self.output = filename

    def action_output_graph(self, *args, **kwargs):
        dg = model.get_graph(*args, **kwargs).generate()
        if isinstance(self.output, str):
            graphviz.Source(dg, filename=self.output, format='png').render(cleanup=True)
        else:
            display(Image(dg.pipe(format='png')))

model = Matter()
machine = GraphMachine(model=model, states=states, initial='A',
                       auto_transitions=False, ordered_transitions=True,
                       title='', show_auto_transitions=False, show_conditions=False,
                       finalize_event='action_output_graph', use_pygraphviz=False)
# use_pygraphviz=Falseを追加

model.get_graph().draw('test.png', prog='dot') #画像出力 ファイル名をここで指定

変更点としては2つです

  1. GraphMachineの定義に"use_pygraphviz=False"を追加(19行目)
  2. 画像出力の関数を変更(最終行)

pygraphvizを使わないことを明示して、dotで出力しろ!
って書いてあげてるわけですね

出力された画像

f:id:dokataponiti:20191008201929p:plain
解説サイトと同じ画像が出て、うまく動いてそうですね!!!


という感じでpygraphvizやcondaを使わずにtransitionsが使えそうです~やったね~
winでpygraphviz入れるのはあきらめそう!

余談ですが、anaconda入れたくなかったのは最近はpipでだいたいどうにかなるので新しいの入れると環境がぐちゃぐちゃになりそうなのを懸念してました。
ばいちゃ