Pythonでnetworkxを使用して有向グラフを描画する方法


101

グラフにマップするスクリプトからのノードがいくつかあります。以下では、AからDに移動するためにArrowを使用したいと思います。おそらく、エッジも色付けされます(赤または何か)。

これは基本的に、他のすべてのノードが存在する場合のAからDへのパスのようなものです。各ノードを都市として想像でき、AからDへの移動には方向(矢印付き)が必要です。

以下のこのコードはグラフを作成します

import networkx as nx
import numpy as np
import matplotlib.pyplot as plt

G = nx.Graph()
G.add_edges_from(
    [('A', 'B'), ('A', 'C'), ('D', 'B'), ('E', 'C'), ('E', 'F'),
     ('B', 'H'), ('B', 'G'), ('B', 'F'), ('C', 'G')])

val_map = {'A': 1.0,
           'D': 0.5714285714285714,
           'H': 0.0}

values = [val_map.get(node, 0.25) for node in G.nodes()]

nx.draw(G, cmap = plt.get_cmap('jet'), node_color = values)
plt.show()

画像のようなものが欲しいです。ここに画像の説明を入力してください ここに画像の説明を入力してください

最初の画像の矢印の頭と2番目の画像への赤色のエッジ。

回答:


86

赤いエッジのみに矢印が付いた完全に肉付けされた例:

import networkx as nx
import matplotlib.pyplot as plt

G = nx.DiGraph()
G.add_edges_from(
    [('A', 'B'), ('A', 'C'), ('D', 'B'), ('E', 'C'), ('E', 'F'),
     ('B', 'H'), ('B', 'G'), ('B', 'F'), ('C', 'G')])

val_map = {'A': 1.0,
           'D': 0.5714285714285714,
           'H': 0.0}

values = [val_map.get(node, 0.25) for node in G.nodes()]

# Specify the edges you want here
red_edges = [('A', 'C'), ('E', 'C')]
edge_colours = ['black' if not edge in red_edges else 'red'
                for edge in G.edges()]
black_edges = [edge for edge in G.edges() if edge not in red_edges]

# Need to create a layout when doing
# separate calls to draw nodes and edges
pos = nx.spring_layout(G)
nx.draw_networkx_nodes(G, pos, cmap=plt.get_cmap('jet'), 
                       node_color = values, node_size = 500)
nx.draw_networkx_labels(G, pos)
nx.draw_networkx_edges(G, pos, edgelist=red_edges, edge_color='r', arrows=True)
nx.draw_networkx_edges(G, pos, edgelist=black_edges, arrows=False)
plt.show()

赤い縁


1
更新された2つの画像がどのように違うかはおかしいです。エッジの色を把握するための+1!
mdml 2013年

上記のコードでは赤でなければならないのに、エッジ(C、E)が赤ではないのはなぜですか?
ブレインストーム

これらの矢印を対象のエッジのみに配置することはできませんか?例:(A、C)および(C、E)
ブレインストーム

@ user1988876:ああ、申し訳ありませんが、無向グラフで作業しているときに(C, E)エッジを選択したため、赤ではありません。red_edgesから返されたエッジからランダムに選択しましたG.edges()。それはあるはずですred_edges = [('A', 'C'), ('E', 'C')]
マリウス

@ user1988876:への個別の呼び出しで、一部のエッジにのみ矢印を付けることが可能draw_networkx_edges()です。コードを整理し、DiGraphの問題を修正しました。
マリウス

47

私はこれを完全にするために入れました。mariusとmdmlから多くのことを学びました。ここにエッジの重みがあります。矢印については申し訳ありません。仕方がないと言っているのは私だけではないようです。これをipythonノートブックでレンダリングできなかったため、エッジウェイトを早く取得するのに問題があったpythonから直接移動する必要がありました。

import networkx as nx
import numpy as np
import matplotlib.pyplot as plt
import pylab

G = nx.DiGraph()

G.add_edges_from([('A', 'B'),('C','D'),('G','D')], weight=1)
G.add_edges_from([('D','A'),('D','E'),('B','D'),('D','E')], weight=2)
G.add_edges_from([('B','C'),('E','F')], weight=3)
G.add_edges_from([('C','F')], weight=4)


val_map = {'A': 1.0,
                   'D': 0.5714285714285714,
                              'H': 0.0}

values = [val_map.get(node, 0.45) for node in G.nodes()]
edge_labels=dict([((u,v,),d['weight'])
                 for u,v,d in G.edges(data=True)])
red_edges = [('C','D'),('D','A')]
edge_colors = ['black' if not edge in red_edges else 'red' for edge in G.edges()]

pos=nx.spring_layout(G)
nx.draw_networkx_edge_labels(G,pos,edge_labels=edge_labels)
nx.draw(G,pos, node_color = values, node_size=1500,edge_color=edge_colors,edge_cmap=plt.cm.Reds)
pylab.show()

ここに画像の説明を入力してください


9
私はこれを実行し、ノードラベルを取得しませんでした。これらを追加する必要があります:node_labels = {node:node for node in G.nodes()}; nx.draw_networkx_labels(G, pos, labels=node_labels)
MadeOfAir 2014

そして、無向グラフがすでにあり、それの有向コピーを複製したい場合はどうなりますか?G.add_edges_from()始点と終点を手動で入力せずにラインを設定する方法はありますか?おそらく、からエッジを追加しますdictか?
FaCoffee 2015年

このセクションの最初のコード行(インポート行以外)は、それがどのタイプのグラフであり、どの種類のエッジを受け入れるかを設定します。有向グラフ(詳細)からグラフ(少ない情報)に移動することはできますが、情報がない場合、または不足している情報を作成する方法がない場合、グラフ(少ない情報)から有向グラフ(詳細)に移動することはできません。別のスタックオーバーフローの質問の例を使って質問を出すことをお勧めします。
Back2Basics 2015年

1
エッジに実際の矢印を付けることは可能ですか?ただ太い方が気に入らない。
Wikunia

1
matplotlibでの矢印の描画はトリッキーであり、現在NetworkXではサポートされていません。プルリクエストは受け入れられます。
Back2Basics 2016年

33

通常のnx.drawの代わりに使用したい場合があります:

nx.draw_networkx(G[, pos, arrows, with_labels])

例えば:

nx.draw_networkx(G, arrows=True, **options)

次のように**変数を初期化することでオプションを追加できます。

options = {
    'node_color': 'blue',
    'node_size': 100,
    'width': 3,
    'arrowstyle': '-|>',
    'arrowsize': 12,
}

また、一部の関数directed=True parameter は、この場合、この状態がデフォルトです。

G = nx.DiGraph(directed=True)

networkxリファレンスはここにあります

矢印画像付きのグラフ


21

グラフの代わりに有向グラフを使用する必要があります。

G = nx.DiGraph()

次に、使用するエッジの色のリストを作成し、それらに渡しますnx.draw(@Mariusで示されています)。

これをすべてまとめると、以下の画像が表示されます。それでも、あなたが示す他の画像はそれほどではありませんが(エッジウェイトの出所がわかりません)、かなり接近しています!出力グラフの外観をより詳細に制御したい場合(たとえば、矢印のように見える矢印を取得する場合)は、GraphvizでNetworkXをチェックしてみます。

ここに画像の説明を入力してください


ああ、乾杯。ドキュメンテーションで矢印の引数を確認できたので、矢印が機能しない理由を理解できなかった。
マリウス

9
import networkx as nx
import matplotlib.pyplot as plt

g = nx.DiGraph()
g.add_nodes_from([1,2,3,4,5])
g.add_edge(1,2)
g.add_edge(4,2)
g.add_edge(3,5)
g.add_edge(2,3)
g.add_edge(5,4)

nx.draw(g,with_labels=True)
plt.draw()
plt.show()

これは、networkxを使用してpython 3.xを使用して有向グラフを描画する簡単な方法です。単純な表現で、変更や色付けなどができますここで生成されたグラフを参照してください。

注:これは単なる単純な表現です。加重エッジは次のように追加できます

g.add_edges_from([(1,2),(2,5)], weight=2)

したがって、再びプロットされます。


1
import networkx as nx
import matplotlib.pyplot as plt

G = nx.DiGraph()
G.add_node("A")
G.add_node("B")
G.add_node("C")
G.add_node("D")
G.add_node("E")
G.add_node("F")
G.add_node("G")
G.add_edge("A","B")
G.add_edge("B","C")
G.add_edge("C","E")
G.add_edge("C","F")
G.add_edge("D","E")
G.add_edge("F","G")

print(G.nodes())
print(G.edges())

pos = nx.spring_layout(G)

nx.draw_networkx_nodes(G, pos)
nx.draw_networkx_labels(G, pos)
nx.draw_networkx_edges(G, pos, edge_color='r', arrows = True)

plt.show()
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.