是否可以控制在python中使用NetworkX绘制节点的顺序?

时间:2018-03-10 15:20:57

标签: python matplotlib networking

我有一个包含许多节点的大型图形对象,我正在尝试绘制图形。由于节点数量众多,许多节点被一个接一个地绘制。这本身不是问题。但是,一小部分节点具有指示其颜色的节点属性。

理想情况下,我能够以这样的方式绘制图形:具有此属性的节点最后绘制在其他节点之上,以便可以在图形上看到它们的分布。

我到目前为止用于生成图表的代码如下所示:

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()

目前输出如下所示:

The current output with all nodes overlapping

这个图形对象本身需要相对较长的时间来生成并且计算密集,所以理想情况下我不必从头开始重新绘制图形。

但是,我很确定图形的绘制顺序与节点添加到图形对象的顺序相同。我已经搜索了一种改变节点存储在图形对象中的顺序的方法,但是给定方向图实际上有一个顺序,我的搜索总是会得到答案,告诉我如何反转图形的方向。

那么,有没有办法规定绘制节点的顺序,或者更改节点存储在某个图形对象中的顺序。

潜在地值得第二个问题,但边缘也被大量节点阻挡。有没有办法在它们后面的节点上绘制边缘?

2 个答案:

答案 0 :(得分:1)

drawdraw_networkx_nodesdraw_networkx_edges的包装器。 与draw不同,这两个函数会返回各自的艺术家(PathCollectionLineCollection,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的直线。结果,它位于左两个节点的前面,而右两个节点的后面。这是结果。

enter image description here