python - networkx - 用两个列表绘制不同颜色的节点
我刚接触networkx,需要一些帮助。我之前搜索过,但没能解决我的问题。我用一个列表作为节点的输入,另外用一个两列的文件来表示边,创建了一个networkx的graphviz图像。还有一个文件包含了第一个列表中的项目,以及对应节点大小的数值。我还有另一个文件,里面有一些和原始列表相同的项目,我希望这些相同的项目能用不同的颜色显示,但不想改变图的布局或结构。
这是我正在测试的一些代码:
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"
hybrids = sys.argv[2]
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)
with open(hybrids, "r") as f3:
hybrids = [line.strip() for line in f3]
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) * 10
sizes.append(x)
g = nx.Graph()
g.add_nodes_from(nodes)
g.add_edges_from(edges)
for node in nodes:
if node in hybrids:
color = 'green'
if node not in hybrids:
color = 'blue'
nx.draw_graphviz(g, prog="fdp", node_color-color, node_size = sizes)
for node in nodes:
if node in hybrids:
g.add_node(node, fillcolor='green')
if node not in hybrids:
g.add_node(node, fillcolor='blue')
A = nx.to_agraph(g)
A.layout()
A.draw(inp + ".png")
plt.figure(1,figsize=(2000,2000))
plt.savefig(out + ".png", dpi = 1000)
plt.show()
我需要能够改变节点的颜色,如果混合列表中的项目在节点列表中存在,而不改变节点列表的结构,以保持原始图像的结构。我尝试过删除与混合列表匹配的节点,然后用两个列表创建不同颜色的节点,但没有颜色变化,而且图的布局发生了很大变化。我希望继续使用graphviz中的“fdp”,除非有人能建议一种方法,让聚类从大到小垂直排列。
在我的搜索中,我发现了A=nx.to_agraph(G),我很喜欢这种表示方式,颜色也按预期变化了,但图像质量很低,对于较大的聚类,什么都看不清。有没有人能建议如何提高图像质量?也许可以把它做大一点,以拉伸大的聚类?
这是原始的graphviz fdp图:
这是A=nx.to_graph的输出:
希望能纠正这两种方法,感谢所有的帮助。
3 个回答
好的,我快搞定了。我已经能把我想要的节点颜色改了,不过图的形状没保持原样。同时,我也能把agraph更新成graphviz的fdp格式。如果有人感兴趣,这里有一些改动:
with open(counts, "r") as f2:
countsdic = defaultdict(list)
for line in f2:
k,v = line.strip().split()
countsdic[k].append(v)
with open(hybrids, "r") as f3:
hybrids = [line.strip() for line in f3]
print hybrids
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) * 10
sizes.append(x)
g = nx.Graph()
#g.add_nodes_from(nodes)
g.add_edges_from(edges)
#for node in nodes:
# if node in hybrids:
# color = 'green'
# if node not in hybrids:
# color = 'blue'
pos=nx.graphviz_layout(g, prog='fdp')
nx.draw_networkx_nodes(g, pos, nodelist=[str(n) for n in nodes], node_color='b', node_size = sizes)
nx.draw_networkx_nodes(g, pos, nodelist=[str(n) for n in nodes if n in hybrids], node_color='g', node_size = sizes)
nx.draw_networkx_edges(g,pos)
#nxgraph(graph)
#for node in nodes:
# if node in hybrids:
# y.add_node(node, fillcolor='green')
# if node not in hybrids:
# g.add_node(node, fillcolor='blue')
A = nx.to_agraph(g)
A.layout(prog="fdp")
A.draw(inp + "2.png")
plt.figure(1,figsize=(2000,2000))
plt.savefig(out + ".png", dpi = 1000)
plt.show()
不过,使用fdp格式的agraph后,所有东西都变成黑色了。我还是想把节点改成特定的颜色,如果有人能帮忙就太好了。我还想保持图的原始形状和格式,只是改变节点的颜色,如果还有人能帮我解决这个问题,我会很感激。我会继续研究这个,如果我搞明白了会再发个答案。感谢所有关注这个帖子的朋友们。(我无法上传更新后的图片,因为太大了)
这是我用来给我的图表上色的代码。
## assign a node attribute, which I am going to color according to
for node in G.nodes():
G.node[node]['category'] = my_category_dict[node]
## put together a color map, one color for a category
color_map = {'type_A':'b', 'type_B':'#FF0099', 'type_C':'#660066'}
## construct a list of colors then pass to node_color
nx.draw(G, node_color=[color_map[G.node[node]['category']] for node in G])
plt.show()
然后我得到了下面这样的图像。我用了比例子中更多的颜色。这是你想要的吗?
另外,这个页面有很多我在绘制图表时觉得很有用的例子。
谢谢你,sophiad,回复得很及时。看起来我一直在寻找的答案其实就在我眼前。我需要做一个颜色的列表,然后传给nx.draw_graphviz。
所以,我找到的正确代码是用来比较两个列表并给一个节点传递特定颜色的:
colors=[]
for n in nodes:
if n in hybrids:
colors.append('g')
else:
colors.append('b')
nx.draw_graphviz(g, prog="fdp", node_color = colors, node_size = sizes)
为了让文本版本和颜色节点版本一致,我只需要把A.layout()改成A.layout(prog="fdp")。
这样做并不会改变布局!
原始图像:
新图像:
新的文本版本: