在Python3中使用NetworkX创建曲线边
我想使用networkx(如果您知道更好的框架,我还想使用另一个框架)来创建 节点位于固定位置的图形。同时,图形的边不应重叠 我以前的代码如下所示:在Python3中使用NetworkX创建曲线边,python,matplotlib,graph,networkx,directed-graph,Python,Matplotlib,Graph,Networkx,Directed Graph,我想使用networkx(如果您知道更好的框架,我还想使用另一个框架)来创建 节点位于固定位置的图形。同时,图形的边不应重叠 我以前的代码如下所示: #!/usr/bin/env python3 import networkx as nx import matplotlib.pyplot as plt # Graph data names = ['A', 'B', 'C', 'D', 'E'] positions = [(0, 0), (0, 1), (1, 0), (0.5, 0.5),
#!/usr/bin/env python3
import networkx as nx
import matplotlib.pyplot as plt
# Graph data
names = ['A', 'B', 'C', 'D', 'E']
positions = [(0, 0), (0, 1), (1, 0), (0.5, 0.5), (1, 1)]
edges = [('A', 'B'), ('A', 'C'), ('A', 'D'), ('A', 'E'), ('D', 'A')]
# Matplotlib figure
plt.figure('My graph problem')
# Create graph
G = nx.MultiDiGraph(format='png', directed=True)
for index, name in enumerate(names):
G.add_node(name, pos=positions[index])
labels = {}
for edge in edges:
G.add_edge(edge[0], edge[1])
labels[(edge[0], edge[1])] = '{} -> {}'.format(edge[0], edge[1])
layout = dict((n, G.node[n]["pos"]) for n in G.nodes())
nx.draw(G, pos=layout, with_labels=True, node_size=300)
nx.draw_networkx_edge_labels(G, layout, edge_labels=labels)
plt.show()
并给出以下结果
如何确保边是“圆形”的,这样它们就不会重叠?正如Paul提到的,现在可以在
draw\u networkx\u Edge
中选择使用FancyArrowPatch
,尽管它只适用于有向图,而且速度非常慢
值得一提的是,我打包了一些旧代码,使用bezier
包从NetworkX图形(或任何边列表)生成漂亮的曲线边,并绘制它们。它可能有用:
使用dataset和ForceAtlas2布局的示例图像:
我认为不能直接使用networkx函数来实现这一点。但是,可以直接使用已计算的节点位置使用matplotlib 调整代码:
import networkx as nx
import matplotlib.pyplot as plt
# Graph data
names = ['A', 'B', 'C', 'D', 'E']
positions = [(0, 0), (0, 1), (1, 0), (0.5, 0.5), (1, 1)]
edges = [('A', 'B'), ('A', 'C'), ('A', 'D'), ('A', 'E'), ('D', 'A')]
# Matplotlib figure
plt.figure('My graph problem')
# Create graph
G = nx.MultiDiGraph(format='png', directed=True)
for index, name in enumerate(names):
G.add_node(name, pos=positions[index])
labels = {}
layout = dict((n, G.node[n]["pos"]) for n in G.nodes())
nx.draw(G, pos=layout, with_labels=True, node_size=300)
ax = plt.gca()
for edge in edges:
ax.annotate("",
xy=layout[edge[0]], xycoords='data',
xytext=layout[edge[1]], textcoords='data',
arrowprops=dict(arrowstyle="->", color="0.5",
shrinkA=5, shrinkB=5,
patchA=None, patchB=None,
connectionstyle="arc3,rad=-0.3",
),
)
plt.show()
给出:
另请参见。在其他NetworkX新闻中,您现在可以指定一个
connectionstyle
参数到nx。绘制网络X\u边
。例如,如果我想要一个具有曲线边的网络,我可以写:
# Compute position of nodes
pos = nx.kamada_kawai_layout(G)
# Draw nodes and edges
nx.draw_networkx_nodes(G, pos)
nx.draw_networkx_edges(
G, pos,
connectionstyle="arc3,rad=0.1" # <-- THIS IS IT
)
#计算节点的位置
位置=nx.kamada_kawai_布局图(G)
#绘制节点和边
nx.绘制网络x\u节点(G、pos)
nx.draw_网络x_边(
G、 pos,
connectionstyle=“arc3,rad=0.1”#
图表的边不应重叠
使用connectionstyle
参数以预先确定的曲率绘制圆弧不会减少边或节点边重叠
对于直边,与其他绘图元素的重叠通常是不可避免的。但是,如果允许我们绘制曲线边,我们可以对每条边进行布线,以尽可能避免其他节点和边。可以通过在每条边中插入控制点,有效地将每条边分割为短子边来实现此效果。我们可以然后使用标准的Fruchterman-Reingold算法(在networkx
中称为spring\u布局
)将图形模拟为一个弹簧系统,其中所有节点和控制点相互排斥,但连接的节点和控制点也相互吸引节点保持固定,同时我们让边缘控制点的位置退火到其平衡位置
我有一个这种方法的实现。该代码是名为netgraph的python网络绘图库的一部分,我是该库的作者。netgraph
与networkx和igraph图形对象完全兼容,因此生成美观的图形应该是简单而快速的
很抱歉,这里无法提供帮助;以下setup.py导致代码出现segfault。Cairocfi==0.9.0 cffi==1.11.5 cycler==0.10.0 decorator==4.3.0 kiwisolver==1.0.1 matplotlib==3.0.0 networkx==2.2 numpy==1.15.2 pgi==0.11.2 pycparser==2.19 pycparser==2.2.2.2.2.2.2.2 dateutil==2.7.3 six==1.11.0 wou你介意分享你的吗?注释格式是最糟糕的-。-“只需执行一个pip安装networkx&&pip安装matplotlib谢谢,我想这是出于好意。但不是我需要的。我以前按照你的建议做了,它缺少几个依赖项。安装它们后,我会遇到segfaults。这不是我想要调试的,所以如果你可以复制安装程序。py如果您成功地使用,可能会有人帮助您,而不会遇到与我相同的问题。当您使用时,您使用的是哪种特定的python版本?3.5、3.6或3.7?AFAIK,目前无法使用networkx
绘制带曲线边的图形,尽管修改源代码并不太困难。networkx
使用matplotlib中的FancyRowPatch
类在绘制网络X\u边
中绘制箭头(由绘制
包裹).FancyRowPatch
支持connectionstyle
参数,该参数不是由draw\u networkx\u Edge
设置的;默认值是一条直线,这是您目前得到的。鉴于MWE的质量,我怀疑您将设法克隆networkx
github repo和patchdraw\u networkx\u Edge
。刚刚尝试将connectionstyle='arc3,rad=0.1'
传递到nx.draw()
,它在一个小(ish)图上非常适合我的用例。刚刚尝试了Colab,结果是,多向图
实现发生了变化。我不得不使用节点
(复数)而不是下一行中的node
:layout=dict((n,G.nodes[n][“pos”])代表n in G.nodes())
(我还应该说,出于某种原因,这似乎只在边缘定向时起作用。这肯定是一个bug,当某个正派的人提出问题并对其进行PR时,它可能会得到修复
#!/usr/bin/env python
import matplotlib.pyplot as plt
import networkx as nx
from netgraph import Graph # pip install netgraph
g = nx.florentine_families_graph()
Graph(g, edge_layout='curved')
plt.show()