【Python基礎】NetworkXでネットワーク図作成:Edgeを矢印にする方法

  • URLをコピーしました!
目次

NetworkX

前回、ネットワーク作成ライブラリNetworkXでNodeとEgdeの色をカラーマップで指定する方法と透明化する方法を試してみました。

今回は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)

実行結果

それでは始めていきましょう。

矢印を表示

まずはとりあえず矢印を表示する方法です。

矢印を表示するには「nx.draw」のオプションに「arrow=True」を追加します。

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, arrows = True, with_labels = True)

このように矢印が表示されますが、方向としては「G.add_edge(‘矢印の始点’, ‘矢印の終点’)」となるようです。

表示可能な矢印の形状

矢印の表示は「nx.draw」に「arrows=True」を追加するだけでしたが、「arrowstyle」のオプションを追加することにより表示する矢印の形状を変えることも可能です。

一覧としてはこんな感じです(G.add_edge(‘A’, ‘B’)としたときの矢印の方向)。

A ← BA → BA ↔︎ B
矢印なし
先が割れている矢印<--><->
先が黒塗りの矢印<|--|><|-|>
先が角括弧]--[]-[
両側が直線なしなし|-|
先が割れている矢印と角括弧]-><-[なし

またこれ以外に特殊な形状として「simple」、「fancy」、「wedge」があります。

それぞれ見ていきましょう。

矢印なし

まずは矢印なしの「-」です。

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, arrows = True, arrowstyle ='-', with_labels = True)

実行結果

矢印を付けたいから「arrows=True」にしているのに矢印なしとは使う場面が出てくるのか分かりませんが、例えば右矢印だと左側は矢印なしだったり、左矢印だったら右側は矢印なしだったりという意味で矢印なしが出てきていると考えられます。

ここからはA→B、A←B、A↔︎Bのように複数の方向を表示できるものに関しては、A→Bのネットワーク図だけ表示します。

先が割れている矢印:->

と言うことでまずは先が割れている矢印(->)です。

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, arrows = True, arrowstyle ='->', with_labels = True)

先が黒塗りの矢印:-|>

次は先が黒塗りの矢印(-|>)です。

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, arrows = True, arrowstyle ='-|>', with_labels = True)

実行結果

先が角括弧:-[

次は先が角括弧(-[)です。

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, arrows = True, arrowstyle ='-[', with_labels = True)

実行結果

両側が直線:|-|

次は両側が直線で止められている形状(|-|)です。

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, arrows = True, arrowstyle ='|-|', with_labels = True)

実行結果

この形状の場合は両側必要で、片側だけにするとエラーとなります。

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, arrows = True, arrowstyle ='-|', with_labels = True)

実行結果
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
~/opt/anaconda3/lib/python3.8/site-packages/matplotlib/patches.py in __new__(cls, stylename, **kw)
   2139         try:
-> 2140             _cls = cls._style_list[_name]
   2141         except KeyError as err:

(中略)

ValueError: Unknown style : -|

先が割れている矢印と角括弧

片方が先が割れている矢印でもう片方が角括弧となっている形状(]->)です。

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, arrows = True, arrowstyle =']->', with_labels = True)

実行結果

ちなみに「先が黒塗りの矢印と角括弧」の組み合わせは準備されていないようでエラーになります。

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, arrows = True, arrowstyle =']-|>', with_labels = True)

実行結果
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
~/opt/anaconda3/lib/python3.8/site-packages/matplotlib/patches.py in __new__(cls, stylename, **kw)
   2139         try:
-> 2140             _cls = cls._style_list[_name]
   2141         except KeyError as err:

(中略)

ValueError: Unknown style : ]-|>

simple

ここからは特殊な形状に関してです。

先ほどもお話ししましたが、特殊な形状としては「simple」、「fancy」、「wedge」の3種類があります。

まずは「simple」から。

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, arrows = True, arrowstyle ='simple', with_labels = True)

実行結果

全体的に太くなった矢印が表示されました。

fancy

次は「fancy」です。

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, arrows = True, arrowstyle ='fancy', with_labels = True)

実行結果

根元が太く、先に向かって細くなる矢印が表示されました。

Wedge

最後は「Wedge」です。

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, arrows = True, arrowstyle ='Wedge', with_labels = True)

実行結果

根本から三角形に伸びている形状が表示されました。

矢印のサイズ変更

上記のように色々な矢印が表示できるのですが、どれも矢印のサイズは小さめのようです。

もし矢印のサイズを変更したい場合は、「arrowsize」のオプションを追加します。

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, arrows = True, arrowsize=50, with_labels = True)

実行結果

ちなみに「arrowsize」のデフォルト値は10です。

矢印の色の変更

矢印の色の変更ですが、こちらは矢印というよりもEdgeの色の変更をすると矢印の色の変更になります。

ということで変更するオプションとしては「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', arrows = True, arrowstyle='simple', with_labels = True)

実行結果

これでEdgeを矢印に変え、色々な形状で表示することが可能になりました。

次回はNodeの形状を変えてみましょう。

ではでは今回はこんな感じで。

よかったらシェアしてね!
  • URLをコピーしました!

コメント

コメントする

目次