【问题标题】:how to get edges from networkx to color differently如何从networkx获得边缘以不同的颜色
【发布时间】:2010-12-06 13:27:53
【问题描述】:

我已经构建了一个树形图像,请参阅 question
现在我有一些主要群体。
一组具有绿色和棕色的节点,并具有“B”和“A”。第二组只有粉色节点和“T”,最后一组有黄色、橙色和蓝色,以及字母“L”、“X”和“H”。颜色是指节点的颜色,字母属于名称。所以我想为不同组的边缘着色。

#taken from draw_graphviz
def get_label_mapping(G, selection): 
    for node in G.nodes(): 
        if (selection is None) or (node in selection): 
            try: 
                label = str(node) 
                if label not in (None, node.__class__.__name__): 
                    yield (node, label) 
            except (LookupError, AttributeError, ValueError): 
                pass


labels = dict(get_label_mapping(G, None))
for label in labels.keys():
if str(label) != "Clade":
        num = label.name.split('-')
        if 'T' in num[0]:
            node_colors.append('#CC6699')
        elif 'X' in num[0]:
            node_colors.append('r')
        else:
            node_colors.append('y')

所以我做了与上面类似的功能,而不是node,我改为get_edge。 试试这个:

  for edge in edges.keys():
        if str(edge) != "Clade":
            if 'T' in edge:
                edge_colors.append('b')

边缘在哪里:

(Clade(branch_length=-0.00193, name='T-7199-8'), Clade(branch_length=0.00494))

也许有一种方法可以判断 T 是否名副其实,然后为边缘着色。 你觉得呢?

有人知道怎么做吗?

谢谢

【问题讨论】:

  • 当您说“如果名称中有 T,则为边缘着色”,您是指 边缘的名称,还是节点的名称(或两个节点)都发生在边缘?另外,你能显示完整的for循环吗?如果我们能确切地看到您正在迭代的内容,就会更容易为您提供帮助。
  • T 在节点的名称中,所以我虽然做了类似的事情:如果 T 在节点中,则为边缘着色。循环在另一个问题中,但我更新了我的问题并提供了更多代码:)
  • 使用 node_colors 我正在更改节点的颜色,例如,如果所有节点都具有红色、边缘为蓝色或类似的颜色,我想要什么。希望我让自己足够清楚
  • 感谢您澄清“姓名”的问题。您现在能否明确说明为边缘着色的条件?例如,只要 任一 个节点的名称以“T”开头,或者只有 两者 都以“T”开头,您是否将边缘着色为蓝色?如果一个节点的名称以“T”开头,而另一个节点的名称以“X”开头,会发生什么情况:你将它涂成蓝色、红色还是两者都不涂?请明确点。尝试考虑特殊情况。
  • 我更新了我的问题,对颜色和名称做了一个小小的解释。颜色代表不同的簇,所以它们不应该混合

标签: python networkx


【解决方案1】:

我猜(因为我不知道 sn-p 如何适应其余代码)您正在迭代 节点,并向每个节点的列表。就像错误消息所暗示的那样,您需要计算出每个 edge 所需的颜色。这会更棘手。

好的,知道了!代码可以稍微整理一下,但这行得通。

#Define your centre node: you need to pull this out of the graph. Call it b.
# The number changes each time: look for a Clade(branch_length=0.03297)
# Its neighbors have branch lengths .00177, .01972, .00774.
b = G.nodes()[112]

# Recursively paint edges below a certain point, ignoring ones we've already seen
def paintedges(graph, startnode, colour):
    for node in graph.neighbors(startnode):
        if node not in alreadyseen: # alreadyseen is in global scope
            graph[startnode][node]["colour"] = colour
            alreadyseen.add(node)
            paintedges(graph, node, colour)

alreadyseen = set([b])
G[b][G.neighbors(b)[0]]["colour"] = "red"
paintedges(G, G.neighbors(b)[0], "red")
G[b][G.neighbors(b)[1]]["colour"] = "blue"
paintedges(G, G.neighbors(b)[1], "blue")
G[b][G.neighbors(b)[2]]["colour"] = "green"
paintedges(G, G.neighbors(b)[2], "green")

# Now make a list of all the colours, in the order networkx keeps the edges
edgecolours = [G[f][t]["colour"] for f,t in G.edges()]
kwargs["edge_color"] = edgecolours

【讨论】:

  • 没错,我正在遍历节点。但我不确定如何从我想要的组中获得优势
  • 从您之前的代码中,BioPython 正在为您生成边缘。除非它能够在生成 networkx 图时为边缘着色,否则您需要自己获取边缘for from, to in thegraph.edges()。请参阅 networkx 文档:networkx.lanl.gov/tutorial/tutorial.html#edge-attributes
  • 好的,所以我必须在 G.edge() 中为边缘做类似的事情,但是我怎么能说属于节点 1 和 2 的边缘应该是红色的。我有黄色、洋红色、绿色、蓝色、棕色节点。例如,如果 node_color =blue 和 green,我想说 color_edge=red
  • @pavid:我添加了一个粗略的示例。我尚未对其进行测试,您可能需要对其进行调整以适应您的目的。
  • 与其遍历每条边,检查是否应该为它着色,以及应该将它着色为哪种颜色,用Graph.subgraph(nbunch) 诱导子图可能更有效,然后迭代通过那些边缘,将颜色属性设置为该组所需的颜色。
猜你喜欢
  • 1970-01-01
  • 2021-07-26
  • 2023-04-07
  • 1970-01-01
  • 1970-01-01
  • 2017-02-23
  • 1970-01-01
  • 2018-04-29
  • 2021-12-29
相关资源
最近更新 更多