Creating curved edges with NetworkX in Python3

有些话、适合烂在心里 提交于 2020-05-27 01:49:19

问题


I would like to use networkx (i would also like to take another framework if you know a better one) to create a graps whose nodes are at fixed positions. At the same time the edges of the graph should not overlap.

My previous code looks like this:

#!/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()

and gives the following result

How do I make sure that the edges are "rounded" so that they don't overlap?


回答1:


As Paul mentions, there is now the option to use the FancyArrowPatch in draw_networkx_edges though it only works on directed graphs and is also very slow.

For what it's worth, I packaged up some old code I had which uses the bezier package to produce nice curved edges from a NetworkX graph (or any edge list, really) and plot them. It may be useful: https://github.com/beyondbeneath/bezier-curved-edges-networkx

Sample image, using the SNAP Facebook dataset and ForceAtlas2 layout:




回答2:


I don't think you can do this directly with networkx functions. But you can use matplotlib directly using the node positions you have calculated.

Adapting your code:

 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()

Gives:

See also this.



来源:https://stackoverflow.com/questions/52588453/creating-curved-edges-with-networkx-in-python3

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!