以单独显示所有边的方式在Python中绘制有向图

以单独显示所有边的方式在Python中绘制有向图,python,networkx,graph-visualization,Python,Networkx,Graph Visualization,我使用Python来模拟在有向图上发生的过程。我想制作这个过程的动画 我遇到的问题是,大多数Python图形可视化库将成对的有向边组合成一条边。例如,显示下图时仅绘制两条边,而我希望分别显示四条边中的每一条: import networkx as nx import matplotlib.pyplot as plt G = nx.MultiDiGraph() G.add_edges_from([ (1, 2), (2, 3), (3, 2), (2, 1),

我使用Python来模拟在有向图上发生的过程。我想制作这个过程的动画

我遇到的问题是,大多数Python图形可视化库将成对的有向边组合成一条边。例如,显示下图时仅绘制两条边,而我希望分别显示四条边中的每一条:

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)

我想展示这样的东西,每个平行边分别绘制:

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)

这个问题似乎处理相同的问题,但解决方案是针对R igraph库的,而不是Python库

有没有一种简单的方法可以使用现有的Python图形可视化库生成这种类型的绘图?如果它能够支持多重图形,那将是一个额外的好处

我对调用外部程序生成图像的解决方案持开放态度。我想生成一系列完整的动画帧,因此解决方案必须是自动化的。

这些工具显示不同的边

例如,给出:

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

  B -> A;
  C -> B;
}
产生:

Graphviz的输入语言非常简单,因此您可以自己生成它,尽管搜索“PythonGraphviz”会找到几个库,包括一个

下面是使用
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(file_name, view=True)

使用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
有关需要查找(0)的原因,请参阅

如果在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)

也许我有点晚了,但我找到了另一个解决你们问题的方法。我张贴它,以便它可以有帮助,如果有人有同样的问题

通过将参数传递给函数,可以使用
matplotlib
使用
networkx
以边缘单独显示的方式绘制有向图:

导入matplotlib.pyplot作为plt
将networkx导入为nx
#创建一个有向多重图
G=nx.multi-digraph()
G.从中添加边([
(1, 2),
(2, 3),
(3, 2),
(2, 1),
])
#绘制图表
plt.图(figsize=(8,8))
nx.绘图(G,连接方式=arc3,弧度=0.1')
plt.show()#退出前暂停
在这里您可以看到结果:


另请参见关于参数
connectionstyle

的说明。您可以使用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()

事实证明,NetworkX可以或,因此它工作得非常好。谢谢两个链接都已失效@Josh Roseni出现以下错误:
格式:“pdf”无法识别。使用其中一个
@LaurenceGonsalves@alper我相信在构建时选择输出格式是可能的。您可能需要安装不同的graphviz发行版,或构建自己的版本。此示例需要更新:
nx。to_pydot
不再可用。相反,您应该
pip安装pydotplus
,然后使用
nx.drawing.nx\u pydot.to\u pydot
。感谢您提出更新此示例的需要,我对其进行了更新
pydotplus
已在上游
networkx
中还原为
pydot
,请参阅。如果pydotplus未找到您的
graphviz
安装,它将抛出
调用异常:未找到graphviz的可执行文件
。一种解决方法是将其添加到当前执行的系统路径中,如下所示:
import os
然后
os.environ[“path”]+=r;C:\Anaconda\envs\testes\Library\bin\graphviz“
,您应该在其中替换graphviz可执行文件所在的文件夹。
pydotplus
pydot
的未维护分支
pydot==1.2.3
将仅在
$PATH
中查找GraphViz可执行文件,原因如中所述以及其中引用的问题。将相关路径添加到环境的
$PATH
变量并不是一种解决方法,而是声明GraphViz所在位置的正确方法。请考虑使用<代码> .BASHC 或等效,而不是在运行时修改<代码> OS.Envion < /C>。