我是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:
首选纠正这两种方法,所有帮助都表示赞赏。
答案 0 :(得分:9)
这是我用于着色图表的内容。
## 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()
然后我得到了如下图像。我使用了比示例中更多的颜色。这是你想要的吗?
另外,this page有许多我在绘制图表时发现有用的示例。
答案 1 :(得分: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”)
它不会改变布局!
原始图片:
新图片:
新文字版本:
答案 2 :(得分:0)
好的,我几乎得到了它。我能够改变我想要的节点的颜色,但它没有保持图形的相同形状,我也能够更新图形表示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()
然而,使用frap格式与agraph使一切变黑。如果有人可以提供帮助,我仍然希望节点具有特定的颜色。我还想保留图形的原始形状和格式,只需更改节点颜色,如果有人仍然可以帮助它。如果我弄明白的话,我会继续研究这个并发布另一个答案。感谢任何看过这篇文章的人。 (我无法发布更新的图片,因为太大了)