2013-03-12 22 views
4

是否可以更改以下代碼以將Child_4放在與Grandchild_0相同的水平級別(從而將Grandchild_4推到自己的級別)?以編程方式爲pygraphviz/dot的networkx的包裝中指定相同排名的節點

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

以上代碼生成如下的佈局,我想通過移位子向下一層以改變以與孫子水平地對齊,其中: img shows a root node, five children, and a single grandchild beneath each child


在Python的網絡圖書館網絡x,我正在使用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包裝中發送等級信息的事情。如果有人能告訴我怎麼可能,我會改變我接受的答案。

回答

3

我找不到通過原始的networkx包裝實現這一點的方法。

相反,我已經爲pygraphviz寫了一個新的包裝,大多數行從the source code複製而來。它爲pygraphviz.add_subgraph(listOfNodes,rank="same")的調用添加一個參數sameRank = []以獲取同名列表的節點列表和for循環。

pos=graphviz_layout_with_rank(G, prog='dot',sameRank=[["Child_4","Grandchild_0"]]) 

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

相關問題