使用Networkx时,我有几个需要以不同方式显示的边缘。为此,我使用连接样式,一些边是直线,另一些是Arc3。问题是,每个边都有一个标签,标签不跟随这些样式中的边缘。
我借用了一个图表作为例子:
#!/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, connectionstyle='Arc3, rad=0.3')
nx.draw_networkx_edge_labels(G, layout, edge_labels=labels, connectionstyle='Arc3, rad=0.3')
# Here is the problem : the labels will not follow the edges
plt.show()
正如这个例子图像所示,这可能导致问题:我们不确定哪个边缘是标签。
有没有一种方法可以画出沿边的标签?
谢谢
发布于 2021-04-24 02:05:51
是的,可以通过使用networkx
有向图绘制有向图的标号边。使用package graphviz
、package networkx
和GraphViz程序dot
的示例
"""How to draw a NetworkX graph using GraphViz.
Requires:
- The Python package `graphviz`: https://github.com/xflr6/graphviz
`pip install graphviz`
- The Python package `networkx`: https://github.com/xflr6/graphviz
`pip install networkx`
- The GraphViz program `dot` in the environment's path
https://graphviz.org/download/
https://en.wikipedia.org/wiki/PATH_(variable)
"""
import graphviz as gv
import networkx as nx
def dump_example_directed_graph():
"""Use GraphViz `dot` to layout a directed multigraph.
Creates a file named 'example_directed_graph' that contains
the rendered graph.
"""
g = example_directed_graph()
h = networkx_to_graphviz(g)
filename = 'example_directed_graph'
fileformat = 'pdf'
h.render(filename, format=fileformat, cleanup=True)
# The argument `view=True` can be given to
# the method `graphviz.dot.Digraph.render`
# to open the rendered file with the
# default viewer of the operating system
def dump_example_undirected_graph():
"""Use GraphViz `dot` to layout an undirected multigraph.
Creates a file named `example_undirected_graph` that contains
the rendered graph.
"""
g = example_undirected_graph()
h = networkx_to_graphviz(g)
filename = 'example_undirected_graph'
fileformat = 'pdf'
h.render(filename, format=fileformat, cleanup=True)
def example_directed_graph():
"""Return a sample directed graph as `networkx.MultiDiGraph`."""
g = nx.MultiDiGraph()
g.add_node(1, label='A')
g.add_node(2, label='B')
g.add_edge(1, 2, label='AB-1')
g.add_edge(1, 2, label='AB-2')
g.add_edge(2, 1, label='BA')
return g
def example_undirected_graph():
"""Return a sample undirected graph as `networkx.MultiGraph`."""
g = nx.MultiGraph()
g.add_node(1, label='A')
g.add_node(2, label='B')
g.add_edge(1, 2, label='AB-1')
g.add_edge(1, 2, label='AB-2')
return g
def networkx_to_graphviz(g):
"""Convert `networkx` graph `g` to `graphviz.Digraph`.
@type g: `networkx.Graph` or `networkx.DiGraph`
@rtype: `graphviz.Digraph`
"""
if g.is_directed():
h = gv.Digraph()
else:
h = gv.Graph()
for u, d in g.nodes(data=True):
h.node(str(u), label=d['label'])
for u, v, d in g.edges(data=True):
h.edge(str(u), str(v), label=d['label'])
return h
if __name__ == '__main__':
dump_example_directed_graph()
dump_example_undirected_graph()
下列文件:
graphviz.dot.Graph
graphviz.dot.Digraph
graphviz.dot.Digraph.node
graphviz.dot.Digraph.edge
networkx.MultiGraph
networkx.MultiDiGraph
上面的代码使用networkx == 2.5.1
、graphviz == 0.16
和GraphViz版本2.40.1。
当前使用matplotlib
的可能性
目前看来,networkx
支持:
networkx.drawing.nx_pylab.draw_networkx_edges
的函数connectionstyle
使用未标记的弯曲边,或edge_labels
的函数edge_labels
标记直线边。因此,对于networkx <= 2.5.1
,标记的曲线边不能用matplotlib
绘制。因此,对于具有一对标记边连接相同节点(例如边缘1 -> 2
和边缘2 -> 1
)的有向图,将在matplotlib
中绘制边缘以重叠,因此并非所有的边缘标签都是可见的。
https://stackoverflow.com/questions/60657926
复制相似问题