29

Python を使用して、有向グラフで行われるプロセスをシミュレートしています。この過程をアニメーションにしたいと思います。

私が遭遇した問題は、ほとんどの Python グラフ視覚化ライブラリが有向辺のペアを 1 つの辺に結合することです。たとえば、次のグラフを表示する場合、 NetworkXは 2 つのエッジのみを描画しますが、4 つのエッジをそれぞれ個別に表示したいと考えています。

import networkx as nx
import matplotlib.pyplot as plt 

G = nx.MultiDiGraph()

G.add_edges_from([
    (1, 2),
    (2, 3),
    (3, 2),
    (2, 1),
])

plt.figure(figsize=(8,8))
nx.draw(G)

NetworkX からの出力。 平行なエッジが重なり合っているため、2 本の線のみが表示されます

各平行エッジを個別に描画して、このようなものを表示したいと思います。

希望する出力形式。 平行なエッジは別々に描画されます

R の igraph の R 相互エッジの問題は同じ問題を扱っているようですが、Python のライブラリではなく、R igraph ライブラリの解決策があります。

既存の Python グラフ視覚化ライブラリを使用して、このスタイルのプロットを作成する簡単な方法はありますか? マルチグラフをサポートできれば、それはおまけです。

私は、外部プログラムを呼び出して画像を生成するソリューションを受け入れます。一連のアニメーション フレーム全体を生成したいので、ソリューションを自動化する必要があります。

4

4 に答える 4

31

Graphvizツールは、明確なエッジを表示するように見えます。

たとえば、次のように指定します。

digraph G {
  A -> B;
  A -> B;
  A -> B;
  B -> C;

  B -> A;
  C -> B;
}

生成するdot:

グラフの例

Graphviz の入力言語は非常に単純なので、自分で生成できますが、「python graphviz」を検索すると、graphvizPyPI のモジュールを含むいくつかのライブラリが見つかります。

graphvizモジュールを使用して上記のグラフを生成する python を次に示します。

from graphviz import Digraph

dot = Digraph()
dot.node('A', 'A')
dot.node('B', 'B')
dot.node('C', 'C')
dot.edges(['AB', 'AB', 'AB', 'BC', 'BA', 'CB'])

print(dot.source)
dot.render(view=True)
于 2012-05-02T18:33:58.767 に答える
13

NetworkX を使用して、ファイル I/O を回避し、レイアウトに pydot 経由でドットを使用する可能な回避策は次のとおりです。

import networkx as nx
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
from io import BytesIO

g = nx.dodecahedral_graph()
d = nx.drawing.nx_pydot.to_pydot(g)
    # `d` is a `pydot` graph object,
    # `dot` options can be easily set
    # attributes get converted from `networkx`,
    # use set methods to control
    # `dot` attributes after creation
png_str = d.create_png()
sio = BytesIO() # file-like string, appropriate for imread below
sio.write(png_str)
sio.seek(0)
img = mpimg.imread(sio)
imgplot = plt.imshow(img)
plt.show()  # added to make the script wait before exiting

seek(0)が必要な理由については、Python で文字列からイメージを作成する方法を参照してください。

IPython (qt) コンソール内の場合、上記はインラインで出力され、より直接的なアプローチは次のとおりです。

import networkx as nx
from IPython.display import Image

g = nx.dodecahedral_graph()
d = nx.drawing.nx_pydot.to_pydot(g)

png_str = d.create_png()
Image(data=png_str)
于 2013-07-24T00:10:34.693 に答える
3

matplotlib インターフェイスを使用して実行できます。

G=nx.MultiGraph ([(1, 2),
   (2, 3),
   (3, 2),
   (2, 1)])
pos = {1: (0.4,0.5), 2: (0.5,0.5), 3: (0.6,0.5)}
nx.draw_networkx_nodes(G, pos, node_color = 'k', node_size = 100, alpha = 1)
ax = plt.gca()
for e in G.edges:
    ax.annotate("",
                xy=pos[e[0]], xycoords='data',
                xytext=pos[e[1]], textcoords='data',
                arrowprops=dict(arrowstyle="->", color="0.5",
                                shrinkA=5, shrinkB=5,
                                patchA=None, patchB=None,
                                connectionstyle="arc3,rad=rrr".replace('rrr',str(2*(e[2]-0.5))
                                ),
                                ),
                )
plt.axis('off')
plt.show()

ここに画像の説明を入力

于 2020-04-30T13:26:13.953 に答える