爲了正確控制pydot有向圖的節點位置和邊緣長度,以便在指向相同方向時邊緣彼此平行,沒有邊直接指向下方,所有節點被繪製到適當的級別 - 必須使用不可見的節點。
在關於此主題「如何控制線角度......」的前期SO Q/A會議中,我瞭解到使用不可見節點來填充丟失的葉節點。這適用於一些樹木,但有一些副作用。
現在,我已經學會爲每個節點添加第三個不可見節點,同時具有左右節點。不可見的節點不會添加到樹中,請注意,但只是繪製到圖中。所以樹仍然可以用於搜索,插入,刪除和其他方法。
這裏是一個graphviz的示例演示瞭解決方案:
digraph {
nodesep=0.35
ordering=out
node[style="filled", fillcolor="grey"]
edge[color="blue", arrowhead="vee"]
{ node[shape=point style=invis] m5 m2 m8 m6 m4 }
5 -> 2
5 -> m5 [weight=100 style=invis]
5 -> 8
2 -> 1
2 -> m2 [weight=100 style=invis]
2 -> 4
8 -> 6
8 -> m8 [weight=100 style=invis]
4 -> 3
4 -> m4 [weight=100 style=invis]
6 -> m6 [weight=100 style=invis]
6 -> 7
}
這裏是我的更新Python代碼片斷這個過程具有典型的樹類自動化:
vT = visualizeTree(0, fileDir, 'bst_graph','.png',1) # instantiate the visualizeTree Object
graph = pydot.Dot(graph_type='digraph', nodesep=.5, pad=.3, size="19.2, 10.1")
graph.set_node_defaults(style="filled", fillcolor="grey")
graph.set_edge_defaults(color="blue", arrowhead="vee")
vT.searchTree(root, sketchTree)
vT.updateGraph()
class visualizeTree(object):
# more code and comments located at project home
def __init__(self, fileCount, fileDir, fileName, fileExt, vidFrames):
def sketchTree(node, stack, find=None, draw=None):
if node.getLeftBranch():
draw(str(node), str(node.getLeftBranch()))
stack.append(node.getLeftBranch())
if node.getRightBranch():
# insert invisible third node in-between left and right nodes
draw(str(node), ":"+str(node), style_type="invisible")
elif node.getRightBranch():
# draw any missing left branches as invisible nodes/edges with dummy unique labels
draw(str(node), ":"+str(node), style_type="invisible")
if node.getRightBranch():
draw(str(node), str(node.getRightBranch()))
stack.append(node.getRightBranch())
elif node.getLeftBranch():
# draw any missing right branches as invisible nodes/edges with dummy unique labels
draw(str(node), ";"+str(node), style_type="invisible")
def draw(self, parent_name, child_name, fill_color="grey", style_type='filled'):
if style_type=="invisible":
# save original edge defaults
weight_ = "100"
saveEdgeDefaults = graph.get_edge_defaults()[0]
graph.set_edge_defaults(style=style_type, color="white", arrowhead="none")
else:
weight_ = "3"
edge = pydot.Edge(parent_name, child_name, style=style_type, weight=weight_)
graph.add_edge(edge)
if style_type=="invisible":
graph.set_edge_defaults(**saveEdgeDefaults)
if not self.nodeNames:
self.nodeNames[parent_name] = pydot.Node(parent_name, label=parent_name, fillcolor=fill_color, style=style_type)
graph.add_node(self.nodeNames[parent_name])
if (parent_name not in self.nodeNames):
self.nodeNames[parent_name] = pydot.Node(parent_name, label=parent_name, fillcolor=fill_color, style=style_type)
graph.add_node(self.nodeNames[parent_name])
if child_name not in self.nodeNames:
self.nodeNames[child_name] = pydot.Node(child_name, label=child_name, fillcolor=fill_color, style=style_type)
graph.add_node(self.nodeNames[child_name])
完整的源代碼可以在項目的家中找到: http://www.embeddedcomponents.com/blogs/2013/12/visualizing-software-tree-structures/
張典型的小圖片,現在畫,因爲我首先想:
即使是大型的樹木可以用類似的幾何形狀可以得出:
的[
可能重複的是有辦法控制線使用pyDot生成圖形時的角度(http://stackoverflow.com/questions/20533753/is-there-a-way-to-control-line-angle-when-producing-graphs-with-pydot) – Skyler
不是重複。我之前的問題是關於用一個角度繪製邊緣而不是直線下降。現在新的問題是如何管理邊緣長度。 – LectureMaker
謝謝編輯PK。我對graphviz中的手動工作有這樣一個問題的答案。當它乾淨地工作時,我會在幾天內使用pydot和python發佈我的答案和示例代碼。 – LectureMaker