在Networkx图形中跟随其边缘的图形标签 [英] Drawing labels that follow their edges in a Networkx graph

查看:45
本文介绍了在Networkx图形中跟随其边缘的图形标签的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用Networkx,我需要以不同的方式显示多个边缘.为此,我使用了连接样式,有些边是直线,有些是 Arc3.问题是每条边都有一个标签,而标签不跟随这些样式中的边.

Working with Networkx, I have several edges that need to be displayed in different ways. For that I use the connectionstyle, some edges are straight lines, some others are Arc3. The problem is that every edge has a label and the label doesn't follow the edges in these styles.

我借了一个图作为示例:

I borrowed a graph as example :

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

这可能会导致问题这个示例图片:我们不确定标签是哪条边.

That can lead to problems as shows this example image : we're not sure for which edge is the label.

有没有办法画沿其边缘的标签?

Is there a way to draw labels that follow their edges ?

谢谢

推荐答案

是的,可以使用 GraphViz 绘制 networkx 有向图的标记边.使用 Python 包 graphviz 的示例,Python 包 networkx ,而GraphViz 程序 dot:

Yes, it is possible to draw labeled edges of networkx directed graphs, by using GraphViz. An example using the Python package graphviz, the Python package networkx, and the GraphViz program 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()

文档:

以上代码使用networkx == 2.5.1graphviz == 0.16和GraphViz 2.40.1版本.

The above code uses networkx == 2.5.1, graphviz == 0.16, and GraphViz version 2.40.1.

似乎当前 networkx 支持:

因此,从 networkx< = 2.5.1 开始,不能使用 matplotlib 绘制带标签的弯曲边缘.因此,对于具有连接相同节点的一对标记边的有向图(例如,边 1 -> 2 和边 2 -> 1>),边缘将在 matplotlib 中绘制以重叠,因此并非所有边缘标签都可见.

So as of networkx <= 2.5.1, labeled curved edges cannot be drawn with matplotlib. As a result, for a directed graph with a pair of labeled edges that connect the same nodes (e.g., an edge 1 -> 2 and an edge 2 -> 1), the edges would be drawn in matplotlib to overlap, so not all edge labels will be visible.

这篇关于在Networkx图形中跟随其边缘的图形标签的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆