如何修改networkx中节点的轮廓颜色?

34 投票
4 回答
22166 浏览
提问于 2025-04-18 00:20

我最近开始学习networkx和用matplotlib.pyplot绘图,想知道怎么修改节点轮廓的颜色(或者其他属性,比如权重)。这里说的“轮廓”不是指两个节点之间的弧线或边,而是默认情况下用来表示节点的圆圈周围的细黑线。

举个例子,当我创建一个只有一个节点的图并显示出来时:

from networkx import *
import matplotlib.pyplot as plt
plt.ion()
G = Graph()
G.add_node(1)
draw(G)

我看到一个红色的节点,周围有一圈细细的黑色轮廓(里面有一个黑色的“1”,那是节点的标签)。我想把这个轮廓的颜色从黑色改成红色(“#FF0000”)或者其他颜色。或者,我能不能完全不显示这个轮廓呢?

我在想,应该有一个属性,类似于edge_color或node_color,可以设置这个轮廓的颜色。不过,我在网上搜索、查看networkx的文档,或者看示例时,都没有找到这样的属性。如果有人能告诉我相关的属性,那就太感谢了!

4 个回答

4

我知道这个讨论已经很久了,但我也在找这个答案,最后找到了一个简单的方法。你可以在绘图函数里加上参数linewidths=0。我觉得这个参数只会影响节点边框的宽度,而不是边的宽度(边的宽度是通过width=x来控制的)。

18

如果你想改变节点边框的颜色,你只需要这样做:

draw(G, linewidths=2)
ax = plt.gca() # to get the current axis
ax.collections[0].set_edgecolor("#FF0000") 

就这么简单。

  • ax.collections[0] 是一个 PathCollection 对象,负责管理节点
  • ax.collections[1] 是一个 LineCollection 对象,负责管理,如果你有的话。

你还可以快速修改这个集合的许多其他属性。

24

NetworkX 2.1 开始,新增了一个叫 edgecolors 的参数,这个参数可以用在 draw_networkx_nodes() 函数上(还有在 draw() 函数上,因为它最终会调用 draw_networkx_nodes() 来绘制节点)。

28

更新(2019年3月): 根据 networkx 2.1 的更新,现在可以直接在 draw() 中使用参数 edge_color 了。

好吧,这个方法有点小技巧,但确实有效。下面是我想到的解决办法。

问题

networkx.draw() 会调用 networkx.draw_networkx_nodes(),然后再调用 pyplot.scatter() 来绘制节点。问题在于,draw_networkx_nodes() 接受的参数并没有传递给 scatter()。(这里有详细信息


为了解决这个问题,我基本上把 networkx.draw() 拆分成了几个部分:draw_networkx_nodesdraw_networkx_edgesdraw_networkx_labels

解决方案

我们可以获取 draw_networkx_nodes() 的返回值——一个 PathCollection,然后对它进行操作:可以使用 PathCollection.set_edgecolor()PathCollection.set_edgecolors() 来设置颜色,前者用单一颜色,后者用颜色列表。

示例代码:

from networkx import *
import matplotlib.pyplot as plt
G = Graph()
G.add_node(1)
# Need to specify a layout when calling the draw functions below
# spring_layout is the default layout used within networkx (e.g. by `draw`)
pos = spring_layout(G)
nodes = draw_networkx_nodes(G, pos)
# Set edge color to red
nodes.set_edgecolor('r')
draw_networkx_edges(G, pos)
# Uncomment this if you want your labels
## draw_networkx_labels(G, pos)
plt.show()

如果你打算经常使用这个,可能更合理(我觉得)是重新定义 draw_networkx_nodes,让它直接把参数传给 scatter。不过上面的办法也能奏效。

如果你想完全去掉标记的边缘,只需把颜色设置为 None,而不是 'r'

撰写回答