networkx - 根据列表或字典值更改节点大小

时间:2014-07-08 15:37:13

标签: python nodes 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] for较小的值为at最少出现在图表上,较大的值显示为相关,但这也不起作用。

我得到的错误是:

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

感谢所有评论和帮助。

2 个答案:

答案 0 :(得分:10)

2014/07/08 12:29 PM:更新以反映来自@ user3358205的评论

问题在于drawing functions in NetworkX要求node_sizes作为list的{​​{1}}输入,而您传递的是int个字符串。你可以read the parameters to the drawing functions here

因为我的程序没有输入文件,所以无法重现输出。但是,这是一个通过传递list list来改变节点大小的示例。请注意,在输出中,我按照大小标记每个节点。

node_sizes

example graph

答案 1 :(得分:4)

通过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