以编程方式在networkx的pygraphviz/dot包装器中指定相同等级的节点

plt*_*plt 5 dot graphviz networkx pygraphviz

是否可以更改以下代码以将Child_4置于与Grandchild_0相同的水平级别(从而将Grandchild_4推送到自己的级别)?

import networkx as nx
import matplotlib.pyplot as plt

G = nx.DiGraph()
G.add_node("ROOT")
for i in xrange(5):
    G.add_node("Child_%i" % i)
    G.add_node("Grandchild_%i" % i)
    G.add_edge("ROOT", "Child_%i" % i)
    G.add_edge("Child_%i" % i, "Grandchild_%i" % i)

pos=nx.graphviz_layout(G,prog='dot')
nx.draw(G,pos,arrows=False)
plt.show()
Run Code Online (Sandbox Code Playgroud)

上面的代码产生了以下布局,我想通过将子级向下移动一级以与孙子级别水平对齐来改变: img显示了一个根节点,五个孩子,以及每个孩子下面的一个孙子


在Python网络库networkx中,我使用graphviz的点引擎来渲染树(遵循此建议).我想通过指定哪些节点应具有相同的高度来控制节点的y位置.节点可能位于树中的不同深度.

我知道如果我通过使用rank=same命令编写自己的graphviz代码(例如,{rank=same; n4 -> p2;}[ ex. ]),我可以控制节点高度.但是,我依赖于networkx.graphviz_layout()[ doc | source ]生成节点位置,graphviz_layout只能向pygraphviz发送命令行参数.我尝试使用变体nx.graphviz_layout(G, prog='dot', args="-Grank=same; n4 -> p2;")失败了. 是否有可能在pygraphviz的NetworkX包装器中描述所需的节点高度,或者我是否需要在pygraphviz周围编写自己的包装器? 编辑:答案为pygraphviz提供了一个新的包装器.它将显着简化在pygraphviz的现有NetworkX包装器中发送排名信息的事情.如果有人能告诉我这是怎么可能的话,我会改变我接受的答案.

plt*_*plt 4

我找不到通过原始 networkx 包装器实现此目的的方法。

相反,我为 pygraphviz 编写了一个新的包装器,其中大部分行都是从源代码复制的。它sameRank = []为相同等级的节点列表添加了一个参数,并for围绕 的调用添加了一个循环pygraphviz.add_subgraph(listOfNodes,rank="same")

def graphviz_layout_with_rank(G, prog = "neato", root = None, sameRank = [], args = ""):
    ## See original import of pygraphviz in try-except block
    ## See original identification of root through command line
    A = nx.to_agraph(G)
    for sameNodeHeight in sameRank:
        if type(sameNodeHeight) == str:
            print("node \"%s\" has no peers in its rank group" %sameNodeHeight)
        A.add_subgraph(sameNodeHeight, rank="same")
    A.layout(prog=prog, args=args)
    ## See original saving of each node location to node_pos 
    return node_pos
Run Code Online (Sandbox Code Playgroud)

在问题示例中,可以通过以下行将 Child_4 推至与 Grandchild_0 相同的水平高度:

pos=graphviz_layout_with_rank(G, prog='dot',sameRank=[["Child_4","Grandchild_0"]])
Run Code Online (Sandbox Code Playgroud)