NetworkX
今回はネットワーク図を作成するためのライブラリ「NetworkX」のお話です。
最初にどういうものかとお見せすると、こんな感じの図を作るためのライブラリです。
どう使うかというと、例えば人間関係のネットワークを可視化したり、言葉のつながりを可視化したりと何からのつながり(ネットワーク)を可視化するために使います。
前にWordCloudで文章を図にして可視化してみるなんてこともしましたが、文字や文章を読んでも頭に入ってこないことが、図になると一瞬で頭に入ったり、忘れにくいなんてこともよくあります。
NetworkXも同じように可視化するライブラリということで理解や記憶に役立つものでしょう。
ということで始めていきましょう。
ライブラリのインストール
まずはライブラリのインストールからです。
いつも通りpipを使ってインストールします。
pip install networkx
インストールをしたらすぐに使えるのかと思って、簡単なプログラムを書いてみましたが、
import networkx as nx
G = nx.Graph()
G.add_node('A')
G.add_node('B')
G.add_node('C')
G.add_edge('A', 'B')
G.add_edge('A', 'C')
nx.draw(G, with_labels = True)
実行結果
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
~/opt/anaconda3/lib/python3.8/site-packages/networkx/utils/decorators.py in _random_state(func, *args, **kwargs)
395 try:
--> 396 random_state_arg = args[random_state_index]
397 except TypeError as e:
IndexError: tuple index out of range
(中略)
~/opt/anaconda3/lib/python3.8/site-packages/networkx/utils/decorators.py in _random_state(func, *args, **kwargs)
398 raise nx.NetworkXError("random_state_index must be an integer") from e
399 except IndexError as e:
--> 400 raise nx.NetworkXError("random_state_index is incorrect") from e
401
402 # Create a numpy.random.RandomState instance
NetworkXError: random_state_index is incorrect
調べてみると「decorder」なるライブラリのバージョンが古いと起こるエラーだそうで、アップデートすると直りました。
ちなみに「decorder」だけアップデートすればいいようなのですが、せっかくなのでAnacondaやAnacondaにインストールされているライブラリでアップデートできるもの全ても一緒にアップデートしておきました。
conda update -n base conda
conda update --all
私の環境は全然アップデートしていなかったので、大量のライブラリをアップデートしなければいけませんでした。
ということでいい機会ですので、皆さんもライブラリをアップデートされることをオススメします。
とりあえず表示してみる
ということでとりあえず表示していきましょう、
まず基礎知識として、2つの言葉を紹介します。
ネットワークの図の中で、各ポイント(丸の部分)は「Node(ノード)」、ポイント間の線の部分は「Edge(エッジ)」と言います。
ネットワークの図を作成するときにはこのNodeに何があるか、そしてEdgeでどのNodeとどのNodeが繋がれているかを指定する必要があります。
ということでプログラムとしてはこんな感じ。
import networkx as nx
G = nx.Graph()
G.add_node('A')
G.add_node('B')
G.add_node('C')
G.add_node('D')
G.add_node('E')
G.add_edge('A', 'B')
G.add_edge('A', 'C')
G.add_edge('A', 'D')
G.add_edge('B', 'D')
G.add_edge('D', 'E')
nx.draw(G, with_labels = True)
上から順に解説していきましょう。
まずはライブラリのインポートです。
「import networkx as nx」として「nx」として使うことが慣例のようです。
「G = nx.Graph()」でグラフエリアの新規作成です。
多分ですがmatplotlibの「fig = plt.figure()」と同じものだと理解しておけばいいのだと思います。
「G.add_node(‘追加するNode名’)」で新しいNodeを追加できます。
今回はA、B、C、D、Eの5つのNodeを追加しました。
G.add_node('A')
G.add_node('B')
G.add_node('C')
G.add_node('D')
G.add_node('E')
Edgeの追加は「G.add_edge(‘Node1’, ‘Node2’)」で、Node1とNode2の間にEdgeを作成します。
こちらも5つほど準備してみました。
G.add_edge('A', 'B')
G.add_edge('A', 'C')
G.add_edge('A', 'D')
G.add_edge('B', 'D')
G.add_edge('D', 'E')
最後に「nx.draw(G, with_labels = True)」でネットワーク図の作成です。
この場合「nx.draw(G)」でGのネットワーク図の作成で、「with_labels = True」はオプションでNodeの丸の中にNode名を表示することを指定しています。
これで作成された図が最初にお見せしたこの図です。
複数のNode、複数のEdgeを一括で登録
先ほどのようにNodeやEdgeを一つずつ追加していくのは分かりやすくていいのですが、ときには一括で追加したいこともあるでしょう。
その場合、Nodeでは「G.add_nodes_from(追加するNodeのリスト)」、Edgeでは「G.add_edges_from(追加するエッジのタプルのリスト)」で一括で追加できます。
import networkx as nx
G = nx.Graph()
G.add_nodes_from(['A', 'B', 'C', 'D', 'E'])
G.add_edges_from([('A', 'B'), ('A', 'C'), ('A', 'D'), ('B', 'D'), ('D', 'E')])
nx.draw(G, with_labels = True)
実行結果
プログラムによるのでしょうが、個人的には一つずつ追加する方がfor文とかで繰り返し処理するのに向いているとは思うのですが、どちらを使うかはお好みでどうぞ。
そして気づいた方もいると思うのですが、今回一つずつNode、Edgeを追加した例と一括で追加した例ではNode、Edgeが同じはずなのに、違う形の図となって出力されました。
ちなみに全く同じプログラムを繰り返し実行しても違う図が出てきます。
多分Nodeをある程度ランダムにばら撒いて、線を引くということをしているのだと思われますが、そのため同じ図が必ず出力されると言うわけではないことに注意してください。
これでネットワークの図は書けるようになりました。
次回はNetworkxでNodeの色やサイズ、またEdgeの色やサイズを変更する方法を試していきましょう。
ではでは今回はこんな感じで。
コメント