python - 如何在Python中使用networkx和matplotlib在同一张图中绘制不同形状和bbox面色的节点?

标签 python python-3.x matplotlib graph networkx

我想使用networkx绘制一个简单的图表。有两个节点,每个节点都带有标签“Python”和“编程”。代码及图表如下:

import networkx as nx

G = nx.DiGraph()
G.add_node(0)
G.add_node(1)
G.add_edge(0,1)

nx.draw_networkx(G,
                pos = {0:(0, 0), 1: (1, 0)},
                node_size = [1000, 2000],
                node_color = ["red","green"],
                node_shape = "s",
                )

enter image description here

我能够分别在两个节点中获得两种不同的颜色红色和绿色,并在每个节点中设置不同的标签。但是,我也想得到两种不同形状的节点。我想要原样的第一个节点和菱形形状的第二个节点,可以使用 node_shape 中的 d 获得。我尝试以 ["s","d"] 形式传递列表,以及以 {0:"s", 1:"d"}< 形式传递字典node_shape 中。

但是,两者都会返回错误。这里如何获取不同形状的节点?是否可以使用其他库(例如 graphviz),如何?

在另一步中,我希望将标签包含在节点内。所以我将node_size设置为0并使用bbox代替,如下所示。

nx.draw_networkx(G,
                pos = {0:(0, 0), 1: (1, 0)},
                node_size = 0,
                 arrows = True,
                 labels = {0:"Python",1:"Programming"},
                 bbox = dict(facecolor = "skyblue")
                )

enter image description here

我可以将标签包含在 bbox 内,但是,箭头没有隐藏,并且两个节点中 bbox 的面颜色相同。在这种情况下如何使面部颜色不同?解决这个问题的替代方法是什么?

最佳答案

Networkx 不支持在一个函数调用中使用多个节点形状,因为节点是使用 matplotlib 的 scatter 绘制的,而该函数不支持在同一函数调用中绘制不同的标记。不过,您可以多次调用 nx.draw_networkx_nodes,每次调用都有不同的节点和形状子集。

将标签包含在节点中是一件棘手的事情。文本框尺寸无法在 matplotlib 中预先计算,因为它支持多个渲染器。因此,您必须绘制一些虚拟文本对象,确定文本框的尺寸,然后返回到所需的尺寸。 Networkx 中不包含此类功能。

如果您愿意使用其他库,那么您想要的大多数功能都可以在 netgraph 中相当轻松地实现。 ,这是我编写和维护的一个库。 支持在一个函数调用中绘制不同的节点形状。箭头应保持可见。更改节点标签背景颜色相当容易。

关于字体大小,在netgraph中,如果未明确设置节点标签的字体大小,则会计算出最大字体大小,以使所有文本框适合相应的节点艺术家。正如您在下面的示例中看到的,该计算存在一个小问题,因为当前实现假定圆形节点形状,因此第一个节点的文本框不太适合方形节点。我会尽快解决这个问题;同时,您必须使用更多的圆形节点形状,或在单独的调用中调整字体大小,如下所示。

enter image description here

#!/usr/bin/env python
import numpy as np
import matplotlib.pyplot as plt
import networkx as nx

from netgraph import Graph # pip install netgraph

graph_data = nx.DiGraph([(0, 1)]) # edge lists or igraph Graph objects are also supported

g = Graph(graph_data,
          node_layout = {0: (0, 0), 1: (1, 0)},
          node_size = {0 : 10, 1 : 20},
          node_color = {0 : "red", 1 : "green"},
          node_labels = {0:"Python", 1:"Programming"},
          node_label_fontdict = {'backgroundcolor' : 'lightgray'},
          node_shape = {0 : "s", 1 : "d"},
          arrows=True,
)

# Netgraph currently does not support multiple values for label backgroundcolors.
# However, all artists are exposed in simple to query dictionaries.
# As node label artists are matplotlib text objects,
# we can vary the node label background colors by using matplotlib.text.Text methods:
g.node_label_artists[0].set_backgroundcolor('salmon')
g.node_label_artists[1].set_backgroundcolor('lightgreen')

# Netgraph assumes circular node shapes when computing fontsizes.
# We hence have to manually adjust the node label fontsizes
# by the ratio of the diagonal to the width in a square.
for node, label in g.node_label_artists.items():
    fontsize = label.get_fontsize()
    label.set_fontsize(fontsize * 1./np.sqrt(2))

plt.show()

关于python - 如何在Python中使用networkx和matplotlib在同一张图中绘制不同形状和bbox面色的节点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71520067/

相关文章:

python - 从pdf转换为文本: lines and words are broken

python - 实例化抽象类时没有错误,即使没有实现抽象方法

python - 使用 grequests 发布和获取

python - Python 中的补丁是什么?

python 类型错误 : get_client_list() missing 1 required positional argument: 'limit'

python - 关于使用 Google App Engine 的反馈?

python - python中lambda函数的地址

python - Python 循环中的嵌套 if 与一个 if

python-3.x - 带有两个 y 轴的 Seaborn 条形图

Python Matplotlib - 如何在 y 轴上指定值?