我有一个包含许多节点的大型图形对象,我正在尝试绘制图形。由于节点数量众多,许多节点被一个接一个地绘制。这本身不是问题。但是,一小部分节点具有指示其颜色的节点属性。
理想情况下,我能够以这样的方式绘制图形:具有此属性的节点最后绘制在其他节点之上,以便可以在图形上看到它们的分布。
我到目前为止用于生成图表的代码如下所示:
import networkx as nx
import matplotlib.pyplot as plt
import numpy as np
import os
import pickle
from pathlib import Path
def openFileAtPath(filePath):
print('Opening file at: ' + filePath)
with open(filePath, 'rb') as input:
file = pickle.load(input)
return file
# Pre manipulation path
g = openFileAtPath('../initialGraphs/wordNetadj_dictionary1.11.pkl')
# Post manipulation path
# g = openFileAtPath('../manipulatedGraphs/wordNetadj_dictionary1.11.pkl')
print('Fetching SO scores')
scores = list()
for node in g.nodes:
scores.append(g.node[node]['weight'])
print('Drawing network')
nx.draw(g,
with_labels=False,
cmap=plt.get_cmap('RdBu'),
node_color=scores,
node_size=40,
font_size=8)
plt.show()
目前输出如下所示:
这个图形对象本身需要相对较长的时间来生成并且计算密集,所以理想情况下我不必从头开始重新绘制图形。
但是,我很确定图形的绘制顺序与节点添加到图形对象的顺序相同。我已经搜索了一种改变节点存储在图形对象中的顺序的方法,但是给定方向图实际上有一个顺序,我的搜索总是会得到答案,告诉我如何反转图形的方向。
那么,有没有办法规定绘制节点的顺序,或者更改节点存储在某个图形对象中的顺序。
潜在地值得第二个问题,但边缘也被大量节点阻挡。有没有办法在它们后面的节点上绘制边缘?
答案 0 :(得分:1)
draw
是draw_networkx_nodes
和draw_networkx_edges
的包装器。
与draw
不同,这两个函数会返回各自的艺术家(PathCollection
和LineCollection
,IIRC)。这些是您的标准matplotlib艺术家,因此他们的相对绘制顺序可以通过他们的zorder属性来控制。
答案 1 :(得分:0)
Pi带Paul Brodersen的答案,如果您希望在前台和后台使用不同的节点,我认为您应该执行以下操作:
对于属于同一层的所有节点,请绘制与该节点相对应的子图,并设置,如下所示:
pos = {...} # some dictionary of node positions, required for the function below
H = G.subgraph(nbunch)
collection = nx.draw_networkx_nodes(H, pos)
collection.set_zorder(zorder)
对属于同一级别的每组节点执行此操作。这很乏味,但是可以解决问题。这是我在研究此问题的基础上创建的一个玩具示例
import matplotlib as mpl
mpl.use('agg')
import pylab
import networkx as nx
G = nx.Graph()
G.add_path([1, 2, 3, 4])
pos = {1 : (0, 0), 2 : (0.5, 0), 3 : (1, 0), 4 : (1.5, 0)}
for node in G.nodes():
H = G.subgraph([node])
collection = nx.draw_networkx_nodes(H, pos)
collection.set_zorder(node)
pylab.plot([0, 2], [0, 0], zorder=2.5)
pylab.savefig('nodes_zorder.pdf', format='pdf')
pylab.close()
这将生成一个图形,然后将每个节点从左到右依次置于更高的级别,因此最左边的节点在背景中最远,最右边的节点在前景中最远。然后,它绘制zorder为2的直线。结果,它位于左两个节点的前面,而右两个节点的后面。这是结果。