2016年1月21日木曜日

Macでpython3の環境構築11---NetworkXの使い方2---

前回「Macでpython3の環境構築10---Networkxの使い方1---」で、なんとかNetworkXでラベルを表示することができたので、今回はNetworkXの基本的な使い方を公式Documentを参考にしながら掘り下げてみようと思います。

グラフの作成(ノードとエッジの作成)

参考:Tutuorial---NetworkX

ノードの作成

簡単な処理から順番に行きます。ノードを追加するには以下のようなコードになります。
import networkx as nx

from matplotlib import pyplot

def main() :
    g=nx.Graph()       # まずは、空のグラフオブジェクトを用意します。
        
    g.add_nodes_from([2,3,4,5])      #  用意したグラフオブジェクトにノード(だけ)を追加します。引数はノードのリストです。
    
    nx.draw_networkx(g,pos=nx.spring_layout(g))     # グラフの描画に必要

    pyplot.show()
if __name__ == '__main__':
    main()


これを実行すると、次のような画面が出てきます。(配置は自動でされます)


エッジの追加

さらにコードを書き足します。
import networkx as nx

from matplotlib import pyplot

def main() :
    g=nx.Graph()
             
    g.add_nodes_from([2,3,4,5])
    
    g.add_edge(2,3)      # 2と3をつなぐエッジを追加する。
    
    nx.draw_networkx(g,pos=nx.spring_layout(g))
    
    pyplot.show()

if __name__ == '__main__':
    main()


これを実行すると、以下のようになり2と3をつなぐエッジが追加されます。
エッジは次のような書き方でも追加できるようです。


import networkx as nx

from matplotlib import pyplot

def main() :
    g=nx.Graph()
               
    g.add_nodes_from([2,3,4,5])
    
    g.add_edge(2,3)
    
    e=(4,5)        
    
    g.add_edge(*e)      # こういう書き方でもエッジは追加できる。
    
    nx.draw_networkx(g,pos=nx.spring_layout(g))
    
    pyplot.show()

if __name__ == '__main__':
    main()


これを実行すると、確かに4と5をつなぐエッジが追加されています。

オプションの指定

挿入している画像のサイズなどを調整したいので、このあたりでオプションの指定をしおきます。
参考:draw_networkx

ノードのサイズ

node_sizeで指定します。デフォルトは300だそうです。
import networkx as nx

from matplotlib import pyplot

def main() :
    g=nx.Graph()
     
    g.add_nodes_from([2,3,4,5])
    
    g.add_edge(2,3)
    
    e=(4,5)
    
    g.add_edge(*e)
    
    nx.draw_networkx(g,pos=nx.spring_layout(g),node_size=500)        # node_sizeで指定します。デフォルトは300だそうです。
    
    pyplot.show()

if __name__ == '__main__':
    main()


これを実行すると、こうなります。


(ラベルの)フォントサイズ

font_sizeで指定します。デフォルトは12らしいです。
import networkx as nx

from matplotlib import pyplot

def main() :
    g=nx.Graph()
      
    g.add_nodes_from([2,3,4,5])
    
    g.add_edge(2,3)
    
    e=(4,5)
    
    g.add_edge(*e)
    
    nx.draw_networkx(g,pos=nx.spring_layout(g),node_size=500,font_size=30)    # font_sizeで指定します。デフォルトは12らしいです。
    
    pyplot.show()

if __name__ == '__main__':
    main()


これを実行すると、こうなります。

ノードの色

node_colorで指定します。デフォルトは今まで見てきたように赤です。
import networkx as nx

from matplotlib import pyplot

def main() :
    g=nx.Graph()
                
    g.add_nodes_from([2,3,4,5])
    
    g.add_edge(2,3)
    
    e=(4,5)
    
    g.add_edge(*e)
    
    nx.draw_networkx(g,pos=nx.spring_layout(g),node_size=500,font_size=30,node_color="b")     # node_colorで指定します。デフォルトは赤です。
    
    pyplot.show()

if __name__ == '__main__':
    main()


これを実行すると、こうなります。
色の指定については(他のオプションもかもしれませんが)、Matplotlibの機能を使って実現されています。
なので、指定方法はMatplotlibに則ります。
よく使う色であれば、青であれば"b"、赤は"r"、緑は"g"、と記号で指定できます。
その他、hexstring(16進指定、#FFFFFFみたいな)だったり、gray shade(灰色の濃淡指定)で0〜1の間の値で指定できたりもします。
より詳しいことは、こちら(Matplotlibのドキュメントページ)やHTMLの色の指定方法などを調べてみましょう。

エッジの太さ

widthで指定します。デフォルトは1.0です。
import networkx as nx

from matplotlib import pyplot

def main() :
    g=nx.Graph()
        
    g.add_nodes_from([2,3,4,5])
    
    g.add_edge(2,3)
    
    e=(4,5)
    
    g.add_edge(*e)
    
    nx.draw_networkx(g,pos=nx.spring_layout(g),node_size=500,font_size=30,node_color="b",width=5.0)     # widthで指定します。デフォルトは1.0です。
    
    pyplot.show()

if __name__ == '__main__':
    main()


これを実行すると、こうなります。

エッジの種類

ノードとノードをつなぐ線の種類はstyleで指定します。デフォルトはsolidですが、その他dashedやdotted、dashdotなどが指定できるようです。
次のコードはdashedを指定してみました。
import networkx as nx

from matplotlib import pyplot

def main() :
    g=nx.Graph()
    
    g.add_nodes_from([2,3,4,5])
    
    g.add_edge(2,3)
    
    e=(4,5)
    
    g.add_edge(*e)
    
    nx.draw_networkx(g,pos=nx.spring_layout(g),node_size=500,font_size=30,node_color="b",width=5.0,style="dashed")    # styleで指定します。デフォルトはsolidです。
    
    pyplot.show()

if __name__ == '__main__':
    main()


実行結果はこちら。

透かし

ノードの透かします。これはalphaで指定します。デフォルトでは当然透かしは入っていないので、それは1.0となっています。
import networkx as nx

from matplotlib import pyplot

def main() :
    g=nx.Graph()
    
    g.add_nodes_from([2,3,4,5])
    
    g.add_edge(2,3)
    
    e=(4,5)
    
    g.add_edge(*e)
    
    nx.draw_networkx(g,pos=nx.spring_layout(g),node_size=500,font_size=30,node_color="b",width=5.0,style="dashed",alpha=0.5)    # alphaで指定します。デフォルトは1.0で透かしは入っていないですが、ここでは0.5と指定しています。
    
    pyplot.show()

if __name__ == '__main__':
    main()


実行結果はこちら。

とりあえず、よく使いそうなところだけ取りあげましたが、NetworkXのドキュメントを見ると他にもいろいろ指定できるようですが、 値として何を指定できるのかがわからないものもある。。。

とりあえずはここまでにしておいて、おいおい分かり次第、紹介します。

2016年1月20日水曜日

Macでpython3の環境構築10---NetworkXの使い方1---

以前、

にて、Matplotlibをインストールしたものの、Networkxのプログラムを実行しても、ノードにラベルがつかない、といろいろ悩んでいた。

で、解決策の一つがわかったので、自分のための忘備録もかねて書いておきたいと思う。

サンプルプログラムとして次のコードを使う。

プログラムの各行の意味などは、また別の機会に書くが、最後の方の描画部分がポイント。
import networkx as nx

from matplotlib import pyplot

def main() :
    g=nx.Graph()
              
    g.add_nodes_from([2,3,4,5])
    
    g.add_edge(2,3)
    
    e=(4,5)
    
    g.add_edge(*e)
    
    g.add_path([1,3,4,2])   #  ノードのリストを渡すと、ノードを順番通りにつなぐ道のりがグラフについかされる。

    nx.draw_networkx(g,pos=nx.spring_layout(g))        # この行が重要。nx.draw()ではない。posを指定しないとエラーになる。
    pyplot.show()
    


if __name__ == '__main__':
    main()


これまでは、nx.draw(g)などとしていたがnx.draw_networkx(g,pos=nx.spring_layout(g)) とすれば改善するようだ。

実際の実行結果がこちら。



となり、確かにノードにラベルがついている。

で話はそれますが、
if __name__ == '__main__':
    main()

の部分についてよく理解していなかったので調べてみた。

調べていたらとてもわかりやすい説明があったので、そちらのリンクを紹介しておきたいと思う。
参考: Python - if __name__ == '__main__': の意味


参考にしたページや文献・書籍
NetworkX documentation
Python - if __name__ == '__main__': の意味