是否可以更改以下代码以将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()
上面的代码产生了以下布局,我想通过将子级向下移动一级以与孙子级水平对齐来进行更改:
在Python网络库networkx中,我正在使用graphviz的点引擎来渲染树(在this recommendation之后)。我想通过指定哪些节点应具有相同的高度来控制节点的y位置。节点可能在树中的不同深度。
我知道如果我使用
rank=same
命令(例如{rank=same; n4 -> p2;}
[ex.])编写自己的graphviz代码,就可以控制节点的高度。但是,我依赖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包装器中发送等级信息的过程。如果有人可以告诉我这怎么可能,我将更改接受的答案。 最佳答案
我找不到通过原始的networkx包装器实现此目标的方法。
取而代之的是,我为pygraphviz编写了新的包装程序,其中大部分行都是从the source code复制而来的。它为同级节点列表列表添加了参数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
在问题示例中,可以通过以下行将Child_4推到与Grandchild_0相同的水平位置:
pos=graphviz_layout_with_rank(G, prog='dot',sameRank=[["Child_4","Grandchild_0"]])
关于graphviz - 在pygraphviz/dot中以编程方式在networkx的包装器中指定相同等级的节点,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15353087/