Networkxで格子グラフを作ってみよう！(入門的内容)

Networkxは、グラフ/ネットワーク理論系の計算を行うためのPythonのパッケージです。
今回は、Networkxの使い方の練習として格子グラフを作ってみようと思います。

## インストール

pipからインストールしてください
```pip3 install networkx```


## グラフの構築

以下の３つのモジュールをインポートしておきます。

```python3
import networkx as nx
import random
import matplotlib.pyplot as plt
```

今回の格子グラフの長方形のサイズを指定し、グラフを作成します。


```python3

    # グラフを作成する長方形の辺の長さを指定
    n = 20
    m = 10

    #グラフを作る
    G = nx.Graph()
```

グラフに点(node)を与えていきます。全部作るのはつまらなかったので、乱数を使って確率0.5で点を追加することにします。

```python3
    #確率0.5でノードを追加
    for i in range(n):
        for j in range(m):
            rate = random.random()
            if rate >= 0.5:
                G.add_node((i,j))
```

次に枝を張ります。列を固定して行成分を見て、隣接２点に点があれば枝を張る、というのを逆に関しても行います。

```py3
    #行方向にエッジを追加
    for i in range(n):
        for j in range(m-1):
            if (i,j) in G and (i,j+1) in G:
                G.add_edge((i,j),(i,j+1))

    #列方向にエッジを追加
    for j in range(m):
        for i in range(n-1):
            if (i,j) in G and (i+1,j) in G:
                G.add_edge((i,j),(i+1,j))
```

## グラフの描画
posで描画の(x,y)座標を与え、nx.draw_networkx_nodes,nx.draw_networkx_edges関数を使って描画します。

```py3
    pos = {n: (n[1], n[0]) for n in G.nodes()}
    nx.draw_networkx_nodes(G, pos, node_size=30, alpha=1, node_color='blue')
    nx.draw_networkx_edges(G, pos, font_size=20, label=1, edge_color="black", width=2)
    plt.savefig('graph_test.png')
```

できました！
![graph_test.png](https://qiita-image-store.s3.amazonaws.com/0/182836/c3c83797-b484-cc70-60be-7868c92c64f6.png)

せっかくなのでもうちょっと遊んでみましょう。
１つの点から多くの枝に伸びている点は色を変えて、大きく表示させてみましょう。
大きさのリスト、色に関する情報のリストを作成して、同様にnx.draw()関数に描画してもらいます。

```py3
    #ノードから出ているエッジが多いほどノードの描画サイズを大きくする
    node_size = [10*len(G[i]) for i in G.nodes()]
    #ノードから出ているエッジが３つ以上であれば赤色でノードを描画する
    node_color = ['red' if len(G[i]) >= 3 else 'blue' for i in G.nodes()]
    pos = {n: (n[1], n[0]) for n in G.nodes()}
    nx.draw_networkx_nodes(G, pos, node_size=node_size, alpha=1, node_color=node_color)
    nx.draw_networkx_edges(G, pos, font_size=20, label=1, edge_color="black", width=2)
    plt.savefig('graph_test.png')
```

できました！
![graph_test2.png](https://qiita-image-store.s3.amazonaws.com/0/182836/5506e7e3-fc3c-d7f1-ec1b-2af16973f16c.png)

最後に今回使ったスクリプトをまとめて載せておきます。

```py3:graph_test.py
import networkx as nx
import random
import matplotlib.pyplot as plt

def main():
    # グラフを作成する長方形の辺の長さを指定
    n = 20
    m = 10

    #グラフを作る
    G = nx.Graph()

    #確率0.5でノードを追加
    for i in range(n):
        for j in range(m):
            rate = random.random()
            if rate >= 0.5:
                G.add_node((i,j))

    #行方向にエッジを追加
    for i in range(n):
        for j in range(m-1):
            if (i,j) in G and (i,j+1) in G:
                G.add_edge((i,j),(i,j+1))

    #列方向にエッジを追加
    for j in range(m):
        for i in range(n-1):
            if (i,j) in G and (i+1,j) in G:
                G.add_edge((i,j),(i+1,j))

    #ノードから出ているエッジが多いほどノードの描画サイズを大きくする
    node_size = [10*len(G[i]) for i in G.nodes()]
    #ノードから出ているエッジが３つ以上であれば赤色でノードを描画する
    node_color = ['red' if len(G[i]) >= 3 else 'blue' for i in G.nodes()]
    pos = {n: (n[1], n[0]) for n in G.nodes()}
    nx.draw_networkx_nodes(G, pos, node_size=node_size, alpha=1, node_color=node_color)
    nx.draw_networkx_edges(G, pos, font_size=20, label=1, edge_color="black", width=2)
    plt.savefig('graph_test2.png')

if __name__ == "__main__":
    main()
```

読んで頂いてありがとうございました。
記事の要望がありましたらコメント欄にお書きください。