Python-graphviz:如何在根目录的相同深度上排列节点

2024-04-26 17:38:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我不知道如何对根树中相同深度的节点强制执行顺序。它曾在this thread中被提出,但没有得到解决。问题是,正如问题的作者所说,graphviz(至少是graphviz的python库)无法维护创建顺序。你知道吗

例如:

g = Graph(format="png")
g.node("x", shape="doublecircle")
g.node("y", shape="circle")  # removed in graph 2
g.node("z", shape="circle")  # removed in graph 2
g.node("nil1", shape="none", label="NIL")
g.node("nil2", shape="none", label="NIL")
g.edge("x", "nil1")
g.edge("x", "y")
g.edge("y", "z")
g.edge("y", "nil2")

上面的代码在我的计算机上生成这个图形

Graph 1

如您所见,y节点和nil1节点交换了位置,但它们不应该交换

但是在我从上面的代码中删除了第3行和第4行之后,输出发生了变化!

Graph 2

这太好笑了。我不知道为什么删除定义两个节点及其形状的两行可以更改输出。即使这两行确实影响了输出,但预期的输出与两个生成的输出中的任何一个都是不同的。你知道我的代码出了什么问题吗?你知道吗


Tags: 代码innonenode节点顺序labelgraphviz
1条回答
网友
1楼 · 发布于 2024-04-26 17:38:34

在同一列上,Graphviz按节点定义的顺序绘制节点。在TB(从上到下)中,相同列上的布局节点按从左到右的顺序绘制。你知道吗

在您的情况下,如果希望nil1节点出现在y节点的之前(左侧),则必须在之前定义它。与znil2相同。你知道吗

这应该起作用:

g = Graph(format="png")
g.node("x", shape="doublecircle")
g.node("nil1", shape="none", label="NIL")
g.node("y", shape="circle")  # removed in graph 2
g.node("nil2", shape="none", label="NIL")
g.node("z", shape="circle")  # removed in graph 2
g.edge("x", "nil1")
g.edge("x", "y")
g.edge("y", "z")
g.edge("y", "nil2")

为了澄清,这里有一个基本的例子。你知道吗

digraph name {
    rankdir=TB
    a b c d
}

在这里,我们按照字母顺序定义了节点,因此我们将得到图上相同的顺序:

如果我们颠倒顺序:

digraph name {
    rankdir=TB
    d c b a
}

图表上的顺序也将颠倒:


回答为什么删除节点定义会影响顺序的问题。如果不需要特殊属性,实际上可以省略定义节点。在这种情况下,当graphviz看到带有未定义节点的edge语句时,它将隐式添加节点定义,例如:

digraph {
  a -> b
  c -> d
}

也就是说:

digraph {
  a
  b
  a -> b
  c
  d
  c -> d
}

因此,在您的例子中,从一开始就删除yz的定义会使它们出现得更晚,就在它们的边缘定义之前。它隐式地将nil1nil2定义放在yz之上。这与我在开始时建议的显式解决方案具有相同的效果。你知道吗

相关问题 更多 >