概要
マルコフチェーン(markov chain)を、PythonのPydotplus(又はPydot)からGraphvizを使って簡単に作るモジュール(markovViz)を作成しました。以下イメージです。

入力条件
pandasのデータフレームのindexを遷移元、columnを遷移先とし、値として遷移確率を設けたデータフレームを入力とします。
以下がイメージです。

表の値の説明(抜粋)
- 状態aからbに遷移する確率:20%
- 状態aからdに遷移する確率: 0%
- 状態bからaに遷移する確率:70%
- 状態bから遷移しない確率:30%
プログラム
以下がソースコードです。適当に張り付けて使ってください。
#必要なモジュールのインポート
import pandas as pd
import numpy as np
import pydotplus
def markovViz(markovdf, fileName='default.png'):
#オブジェクトを定義
graph = pydotplus.Dot(graph_type='digraph')
#ノードを追加
for c in df.columns:
node = pydotplus.Node(c)
graph.add_node(node)
#エッジを追加
for i in df.index:
for c in df.columns:
if df.ix[i, c] > 0:
edge = pydotplus.Edge(graph.get_node(i)[0], graph.get_node(c)[0])
edge.set_label('{:.1f}'.format(df.ix[i, c]))
graph.add_edge(edge)
#グラフ描画
graph.write_png(fileName, prog='dot')
いろいろ試してみる
せっかく作ったのでいろいろ試してみました。
まずは例題の結果。
if __name__ == "__main__": df = pd.DataFrame(index=['a', 'b', 'c', 'd'], columns=['a', 'b', 'c', 'd'], data=[[0.6, 0.2, 0.2, 0.0], [0.7, 0.3, 0.0, 0.0], [0.0, 0.4, 0.5, 0.1], [0.1, 0.3, 0.3, 0.3]]) markovViz(df)

ラベルと線の間の余白や線の曲がりがちょっと気になりますが、まずは使えるレベルと言えそうですね。
10の状態を設けた場合の結果。
if __name__ == "__main__":
#ランダムなデータを作成
np.random.seed(0)
data = np.random.rand(10, 10)
#行方向の合計が1になるように正規化
data = (data / data.sum(axis=0)).T
#DataFrame作成
df = pd.DataFrame(data, index=np.arange(10).astype('str'), columns=np.arange(10).astype('str'))
#グラフ作成
markovViz(df)

うまくかけていますね。こういうのを見ると、Graphvizやるなぁ、という気がします。
20の状態を設けた場合の結果。

ここまでくると何が何だかわかりませんが、参考ということで。