yukke::note

technical note

networkxでグラフを描画するとmatplotlibのエラーでラベルが表示できない

まえがき

networkxというグラフ理論を扱うpythonのライブラリがある。networkxのグラフオブジェクトは、networkx.draw_networkx_nodes()networkx.draw_networkx_edges()などのメソッドでグラフ構造を可視化することができる。

import matplotlib.pylab as plt
import networkx

def show(g):
    text_font = "sans-serif"
    node_color = 'blue'
    node_alpha = 0.4
    pos = networkx.pygraphviz_layout(g, prog="circo")
    networkx.draw_networkx_nodes(g, pos, node_color="pink", alpha=node_alpha+0.5)
    networkx.draw_networkx_edges(g, pos, edge_color="blue", alpha=node_alpha, arrows=False)
    networkx.draw_networkx_labels(g, pos, font_size=12, font_family='sans-serif')
    plt.show()

if __name__ == '__main__'
    G = networkx.Graph() # 無向グラフ
    G.add_nodes_from(['A', 'C', 'B', 'E', 'D', 'G', 'F', 'I', 'H']) # nodeを作る
    G.add_edges_from([('A', 'I'), ('A', 'C'), ('A', 'B'), ('C', 'F'), ('B', 'D'), ('E', 'F'), ('D', 'G'), ('G', 'H')]) # edgeを作る
    show(G) 

問題

nodesやedgesにint/float型ではない、str型を渡すと以下のようなエラーがでる。グラフは描画できるが、ノードに何も表示されないのでつらい。

  File "/Users/yukke/.pyenv/versions/2.7.8/lib/python2.7/site-packages/matplotlib/artist.py", line 59, in draw_wrapper
    draw(artist, renderer, *args, **kwargs)
  File "/Users/yukke/.pyenv/versions/2.7.8/lib/python2.7/site-packages/matplotlib/figure.py", line 1079, in draw
    func(*args)
  File "/Users/yukke/.pyenv/versions/2.7.8/lib/python2.7/site-packages/matplotlib/artist.py", line 59, in draw_wrapper
    draw(artist, renderer, *args, **kwargs)
  File "/Users/yukke/.pyenv/versions/2.7.8/lib/python2.7/site-packages/matplotlib/axes/_base.py", line 2092, in draw
    a.draw(renderer)
  File "/Users/yukke/.pyenv/versions/2.7.8/lib/python2.7/site-packages/matplotlib/artist.py", line 59, in draw_wrapper
    draw(artist, renderer, *args, **kwargs)
  File "/Users/yukke/.pyenv/versions/2.7.8/lib/python2.7/site-packages/matplotlib/text.py", line 538, in draw
    bbox, info, descent = self._get_layout(renderer)
  File "/Users/yukke/.pyenv/versions/2.7.8/lib/python2.7/site-packages/matplotlib/text.py", line 311, in _get_layout
    ismath=False)
  File "/Users/yukke/.pyenv/versions/2.7.8/lib/python2.7/site-packages/matplotlib/backends/backend_macosx.py", line 166, in get_text_width_height_descent
    six.text_type(s), family, size, weight, style)
ValueError: failed to convert font family name to ASCII

f:id:soh3914:20141209174608p:plain

matplotlibのbackendを変えればよい

matplotlibは、GTKAggやTkAggなど、異なるグラフィックエンジンを使用できる。$HOME/.matplotlib/~/matplotlibrcにその設定を書くことでバックエンドを切り替えることができる。どうも、デフォルトのバックエンドが問題で、backend : TkAggを設定ファイルに追記したら、治った。

f:id:soh3914:20141209174836p:plain

今度は、ちゃんとnodeにラベルが表示されている。めでたい。