NetworkX
前回、ネットワーク作成ライブラリNetworkXをインストールして、とりあえず表示をしてみました。
今回はNodeの色と大きさ、そしてEdgeの色と太さを変更する方法を試していきます。
まずは基本となるプログラムですが、NodeもEdgeも一つずつ追加しているこの形を使っていきましょう。
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)
実行結果
それでは始めていきましょう。
Nodeの色を一括で変更
まずはNodeの色を一括で変更する方法です。
全てのNodeの色を一括で変更するには「nx.draw」のオプションに「node_color=’色’」を追加します。
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, node_color='red', with_labels = True)
実行結果
Edgeの色を一括で変更
次にEdgeの色を一括で変更する方法を見ていきましょう。
Edgeの色を変更する場合も「nx.draw」のオプションに追加しますが、オプションとしては「edge_color=’色’」となります。
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, edge_color='red', with_labels = True)
実行結果
Nodeの大きさを一括で変更
次にNodeの大きさを一括で変更する方法です。
Nodeの大きさを一括で変更する場合は、「nx.draw」のオプションに「node_size=サイズ」を追加します。
注意すべき点としては、Nodeのデフォルトのサイズは300ということです。
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, node_size=1000, with_labels = True)
実行結果
Edgeの太さを一括で変更
次はEdgeの太さを一括で変更する方法です。
Edgeの太さを一括で変更する場合も「nx.draw」のオプションに追加しますが、この場合は単純に「width=太さ」のオプションを追加します。
(個人的にはedge_widthかと思ったので、ちょっと意外でした)
こちらのデフォルト値は1のようです。
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, width=5, with_labels = True)
実行結果
Nodeの色を個別で変更
次にNodeの色を個別に変更する方法です。
特にNodeを分類するなどのときに効果的でしょう。
この場合はNodeの順に合わせた色のリストを作って、「nx.draw」の色のオプション「node_color」に読み込ませます。
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')
nodecolor = ['Red', 'Green', 'Blue', 'Purple', 'Magenta']
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, node_color = nodecolor, with_labels = True)
実行結果
色々調べていたときに「add_node」のオプションとして「color」を追加している例もあったのですが、何故か私の環境では使えませんでした。
もしかしたらNetworkXのバージョン等で色の指定の仕方が違っていたりするのかもしれません。
import networkx as nx
G = nx.Graph()
G.add_node('A', color='Red')
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)
実行結果
Edgeの色を個別で変更
次にEdgeの色を個別に変更する方法ですが、こちらもNodeの色を個別に変更する方法と同じく、色のリストを作成し、「nx.draw」の「edge_color」に読み込ませます。
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')
edgecolor = ['Red', 'Green', 'Blue', 'Purple', 'Magenta']
nx.draw(G, edge_color = edgecolor, with_labels = True)
実行結果
Nodeの大きさを個別で変更
次はNodeの大きさを個別で変更する方法です。
こちらもNodeの色を個別で変更する方法と同じで、大きさのリストを作り、「nx.draw」の「node_size」に読み込ませます。
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')
nodesize = [300, 600, 900, 1200, 1500]
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, node_size = nodesize, with_labels = True)
実行結果
Edgeの太さを個別で変更
次はEdgeの太さを個別に変更する方法です。
こちらも同じく太さのリストを作り、「nx.draw」の「width」のオプションに読み込ませます。
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')
edgewidth = [1, 2, 3, 4, 5]
nx.draw(G, width = edgewidth, with_labels = True)
実行結果
NodeとEdgeの数を取得
ここからはNodeやEdgeの色をカラーマップで指定する方法を紹介します。
カラーマップを使うにはNodeとEdgeの数を取得する必要があります。
何故かと言うと先ほどのカラーマップを等分割し、色を取得してくるからです。
Nodeの数を取得するには「nx.number_of_nodes(G)」、Edgeの数を取得するには「nx.number_of_edges(G)」を使います。
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')
print(nx.number_of_nodes(G))
print(nx.number_of_edges(G))
実行結果
5
5
ここでは最後の「nx.draw」を消しているのでネットワークの図は表示されません。
NodeもEdgeも5つずつ作成したので、両方とも「5」と表示されました。
Nodeにカラーマップを使う方法
それではまずはNodeの色をカラーマップで指定してみましょう。
import networkx as nx
import matplotlib.pyplot as plt
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')
num_node = nx.number_of_nodes(G)
nx.draw(G, node_color=range(num_node), cmap=plt.cm.Reds, with_labels = True)
実行結果
まずmatplotlibのカラーマップを使用するため、maplotlibをインポートしています(import matplotlib.pyplot as plt)。
「num_node = nx.number_of_nodes(G)」でNodeの数を取得し、変数num_nodeに格納しています。
そして「nx.draw(G, node_color=range(num_node), cmap=plt.cm.Reds, with_labels = True)」の「node_color=range(num_node)」でNodeの数からリストを作成します。
そして「cmap=plt.cm.Reds」としてmatplotlibのカラーマップを読み込むことで自動でカラーマップを使ったネットワーク図を作成してくれます。
ちなみにmatplotlibをインポートせずに「cmap=’Reds’」のように直接カラーマップ名を使っている例も見かけたことがありますが、私の環境ではうまく動かなかったので、このようなやり方にしました。
Edgeにカラーマップを使う方法
次にEdgeの色をカラーマップで指定する方法です。
Nodeの色をカラーマップを使って指定した方法とほぼ同じですが、最後の「cmap」のオプション名が「edge_cmap」に変わります。
import networkx as nx
import matplotlib.pyplot as plt
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')
num_edge = nx.number_of_edges(G)
nx.draw(G, edge_color=range(num_edge), edge_cmap=plt.cm.Blues, with_labels = True)
実行結果
これでEdgeの色の指定もカラーマップを使ってできました。
そしてもちろん先ほどのNodeの色をカラーマップで指定した方法と合わせると両方一度にカラーマップを使って色を変えることが可能になります。
import networkx as nx
import matplotlib.pyplot as plt
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')
num_node = nx.number_of_nodes(G)
num_edge = nx.number_of_edges(G)
nx.draw(G, node_color=range(num_node), edge_color=range(num_edge), cmap=plt.cm.Reds, edge_cmap=plt.cm.Blues, with_labels = True)
実行結果
ネットワークの図でNodeの色やEdgeの色で重要度を示したりもするので、この方法を覚えておくと一段と作成したネットワーク図が見やすく、有用なものになりそうですね。
Nodeを透明化する方法
ここはオマケですが、Nodeを透明化する方法も試してみました。
Nodeの透明化は「nx.draw」のオプション「alpha」を指定するだけです。
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, alpha=0.5, with_labels = True)
実行結果
指定する数字の範囲が1(100%=0%透明化)から0(0%=100%透明化)の間の小数ですので気をつけてください。
また色をリストで指定したように、透明化もリストで指定できるかと思ってやってみたのですが、どうやらできないようです。
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')
node_alpha = [1, 0.8, 0.6, 0.4, 0.2]
nx.draw(G, alpha=node_alpha, with_labels = True)
実行結果
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/var/folders/sp/hg7p80kx22s7vct7yb0zl5cm0000gn/T/ipykernel_46982/1072310590.py in <module>
17 node_alpha = [1, 0.8, 0.6, 0.4, 0.2]
18
---> 19 nx.draw(G, alpha=node_alpha, with_labels = True)
(中略)
TypeError: alpha must be numeric or None, not <class 'list'>
ここまでできるならもう少しだと思うのですが…ちょっと残念ですね。
ということで今回はNodeとEdgeの色の指定にカラーマップを使う方法とNodeの透明化を試してみました。
次回はEdgeの矢印の表示に関して色々試していきたいと思います。
ではで今回はこんな感じで。
コメント