2014-07-08 55 views
3

我试图在networkx中创建一个图。我无法为节点分配不同的节点大小。networkx - 根据列表或字典值更改节点大小

这里是我的代码,我一直在玩:

import sys 
from collections import defaultdict 
import networkx as nx 
import matplotlib.pyplot as plt 

inp = sys.argv[1] 
cluster = sys.argv[1] + ".cluster" 
counts = sys.argv[1] + ".counts" 

with open(cluster, "r") as f1: 
     edges = [line.strip().split('\t') for line in f1] 

with open(counts, "r") as f2: 
     countsdic = defaultdict(list) 
     for line in f2: 
       k,v = line.strip().split() 
       countsdic[k].append(v) 

tmp = [] 

for el in sum(edges, []): 
     tmp.append(el) 

nodes = [] 

for t in tmp: 
     if t not in nodes: 
       nodes.append(t) 

node_sizes = {} 
for n in nodes: 
     node_sizes[n] = ' '.join(countsdic[n]) 
print node_sizes 

nodes2 = [] 
sizes = [] 
for k in node_sizes.keys(): 
     nodes2.append(k) 
for v in node_sizes.values(): 
     sizes.append(v) 
print nodes2 
print len(nodes2) 
print sizes 
print len(sizes) 
g = nx.Graph() 
g.add_nodes_from(nodes) 
g.add_edges_from(edges) 

nx.draw_random(g, node_list = nodes2, node_size = sizes) 

# I've also tried assigning node_list and node_size with node_sizes.keys() and node_sizes.values() 

plt.savefig(inp + "." + gtype + ".png") 
plt.show() 

如果我不尝试更改节点的大小,我得到一个相当不错的图形。字典的值在1到10之间,有一些高的值,比如156,我需要是最大的,所以我需要做一些事情:node_sizes = [n * 100 for n in sizes]最少出现在图表上,而较大的值看起来相关,但这也不起作用。

我得到的错误是:

Exception in Tkinter callback 
Traceback (most recent call last): 
    File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1489, in __call__ 
    return self.func(*args) 
    File "/usr/lib/pymodules/python2.7/matplotlib/backends/backend_tkagg.py", line 276, in resize 
    self.show() 
    File "/usr/lib/pymodules/python2.7/matplotlib/backends/backend_tkagg.py", line 348, in draw 
    FigureCanvasAgg.draw(self) 
    File "/usr/lib/pymodules/python2.7/matplotlib/backends/backend_agg.py", line 451, in draw 
    self.figure.draw(self.renderer) 
    File "/usr/lib/pymodules/python2.7/matplotlib/artist.py", line 55, in draw_wrapper 
    draw(artist, renderer, *args, **kwargs) 
    File "/usr/lib/pymodules/python2.7/matplotlib/figure.py", line 1034, in draw 
    func(*args) 
    File "/usr/lib/pymodules/python2.7/matplotlib/artist.py", line 55, in draw_wrapper 
    draw(artist, renderer, *args, **kwargs) 
    File "/usr/lib/pymodules/python2.7/matplotlib/axes.py", line 2086, in draw 
    a.draw(renderer) 
    File "/usr/lib/pymodules/python2.7/matplotlib/artist.py", line 55, in draw_wrapper 
    draw(artist, renderer, *args, **kwargs) 
    File "/usr/lib/pymodules/python2.7/matplotlib/collections.py", line 717, in draw 
    for x in self._sizes] 
TypeError: Not implemented for this type 

几个小时搜索谷歌后,我无法来解决问题。下面是一个在不改变节点大小产生:

An example output of the graph where all nodes are the same size. (NEED ALL NODES RELATIVE TO VALUE SIZE

所有评论和帮助表示赞赏。

回答

7

2014年7月8日下午12点29分:更新以反映@评论user3358205

的问题是drawing functions in NetworkX需要node_sizes是输入作为intlist一个S,而你是传递一个list的字符串。你可以read the parameters to the drawing functions here

因为我没有输入文件到您的程序,我无法重现您的输出。但是,下面是一个示例,您可以通过传递listnode_sizes来改变节点的大小。请注意,在输出中,我将按照它们的大小标记每个节点。

import sys, networkx as nx, matplotlib.pyplot as plt 

# Create a list of 10 nodes numbered [0, 9] 
nodes = range(10) 
node_sizes = [] 
labels = {} 
for n in nodes: 
     node_sizes.append(100 * n) 
     labels[n] = 100 * n 

# Node sizes: [0, 100, 200, 300, 400, 500, 600, 700, 800, 900] 

# Connect each node to its successor 
edges = [ (i, i+1) for i in range(len(nodes)-1) ] 

# Create the graph and draw it with the node labels 
g = nx.Graph() 
g.add_nodes_from(nodes) 
g.add_edges_from(edges) 

nx.draw_random(g, node_size = node_sizes, labels=labels, with_labels=True)  
plt.show() 

example graph

+0

感谢您的回答mdml。所以,我将字典中的值附加到一个名为sizes的新列表中,但它不起作用,但它是一个列表。你能解释为什么它没有? –

+0

@ user3358205:它是一样的错误信息吗?如果是这样,你可以[简化你的问题中的代码](http://stackoverflow.com/help/mcve)(包括输入)? – mdml

+0

我想我弄清楚为什么我的代码不工作。我将字典node_sizes.values()中的字符串附加到列表大小,而不是整数。 –

2

随着MDML的回答我能回答解决问题。事实证明,我将一个列表传递给了networkx的节点大小,尽管它并不喜欢这个列表。我将字符串附加到列表中,而不是整数。改变v到和INT()解决了这个问题,然后我再乘以100,因为有些值很小,使节点大小有关:

with open(cluster, "r") as f1: 
    edges = [line.strip().split('\t') for line in f1] 

with open(counts, "r") as f2: 
    countsdic = defaultdict(list) 
    for line in f2: 
     k,v = line.strip().split() 
     countsdic[k].append(v) 

tmp = [] 

for el in sum(edges, []): 
    tmp.append(el) 

nodes = [] 

for t in tmp: 
    if t not in nodes: 
     nodes.append(t) 

node_sizes = {} 
for n in nodes: 
    node_sizes[n] = ' '.join(countsdic[n]) 

sizes = [] 
for v in node_sizes.values(): 
    x = int(v) * 100 
    sizes.append(x) 

g = nx.Graph() 
g.add_nodes_from(nodes) 
g.add_edges_from(edges) 

nx.draw_random(g, node_size = sizes) 

plt.savefig(inp + "." + gtype + ".png") 
plt.show() 

我一直在寻找的图形输出:

enter image description here