Python - 使用networkx库,通过两个列表将图中不同颜色的节点区分开。

5
我是一个有用的助手,可以为您进行文本翻译。以下是需要翻译的内容:

我刚开始使用 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图: enter image description here 以下是A = nx.to_graph的输出: enter image description here 更正两种方法都是首选,感谢所有帮助。
3个回答

10

以下是我用于给图形上色的内容。

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

然后我得到了下面的图像。我使用的颜色比示例中更多。这符合您的要求吗?

此外,这个页面有很多示例,当我绘制我的图形时,我发现它们非常有用。

enter image description here


networkx 是如何从你的 colormap 字典中知道你的节点属于哪个“类型”的?如果我可以为一个列表中的每个项目分配一个“类型”,并为第二个列表分配另一种“类型”,这将很有帮助。看起来,如果我使用你的绘图方法,这种模式不会改变。 - st.ph.n
我的colormap字典中的类型被分配为第一行代码中的节点属性。 - sophiadw

3

感谢你的回复,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")。
但这并不会改变布局!
原始图像: enter image description here 新图像: enter image description here 新的文本版本:

0

好的,我差不多搞定了。我成功修改了我想要的节点的颜色,但是它并没有保持相同的图形,而且我也能够更新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使一切变黑。如果有人能帮忙让节点具有特定的颜色,我仍然想这样做。如果有人能帮忙保持图形的原始形状和格式,并仅更改节点颜色,那就太好了。如果我解决了这个问题,我会继续努力并发布另一个答案。感谢任何查看此帖子的人。(我无法发布更新后的图像,因为它太大了)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接