NetworkX
前回、ネットワーク作成ライブラリNetworkXでNodeやEdgeの色を変えたり、大きさ、太さを変える方法を試してみました。

今回はもう少しNodeやEdgeの色に関して試していきましょう。
前回は色の指定はリストを使って、一つずつ行っていきましたが、NodeやEdgeの数が増えれば、一つ一つ指定するのは難しくなっていきます。
そこで使うのがカラーマップと呼ばれる既にグラデーションになっている色のセットを使う方法です。
どんな色のセットがあるのかはこちらのページをご覧ください。
と言うことで今回はこのカラーマップなるものをどうやって使うのか見ていきましょう。
また最後にオマケとして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)
実行結果

それでは始めていきましょう。
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の矢印の表示に関して色々試していきたいと思います。

ではで今回はこんな感じで。
コメント