python 中 graphviz 中的图形节点位置
Graph node position in graphviz in python
我一直在寻找在 python 的 graphviz 中指定图形中节点位置的方法。我在点中找到了 rank command 的子图,这正是我要找的,但我找不到在 python 中将子图和 graphviz 中的等级结合起来的方法。我也尝试强制节点位置,但也没有用。我创建了一个我想要实现的简单示例。
这是我的代码:
from graphviz import Digraph
top_nodes = ['a', 'b', 'c']
other_nodes = ['d', 'e', 'f', 'g', 'm', 'n']
g = Digraph('test', format='png')
for n in top_nodes:
g.node(str(n), color='red')
for n in other_nodes:
g.node(str(n))
g.edge('a', 'd')
g.edge('d', 'g')
g.edge('g', 'm')
g.edge('m', 'n')
g.edge('b', 'e')
g.edge('b', 'f')
g.edge('e', 'n')
g.edge('c', 'f')
g.view()
这是输出:
我希望红色节点('sources')在同一层级的图形顶部,只要保留层次布局,其余节点的位置并不那么重要。
尝试 rank = same 语句
digraph G {
a b c d e f g m n
{rank = same; a; b; c;}
a->d
d->g
g->m
m->n
b->e
b->f
e->n
c->f
}
我遇到了同样的问题,发现使用子图解决了问题。
from graphviz import Digraph
top_nodes = ['a', 'b', 'c']
other_nodes = ['d', 'e', 'f', 'g', 'm', 'n']
g = Digraph('test', format='png')
s = Digraph('subgraph')
s.graph_attr.update(rank='min')
for n in top_nodes:
s.node(str(n), color='red')
for n in other_nodes:
g.node(str(n))
g.edge('a', 'd')
g.edge('d', 'g')
g.edge('g', 'm')
g.edge('m', 'n')
g.edge('b', 'e')
g.edge('b', 'f')
g.edge('e', 'n')
g.edge('c', 'f')
g.subgraph(s)
g.view()
image output
从你的代码开始,使用子图上下文就足够了,只需添加
with g.subgraph() as s:
s.attr(rank = 'same')
for n in top_nodes: s.node(n)
这似乎比显式声明子图并将其添加到原始图更容易。
顺便说一句,此解决方案生成与 @RaHo 答案中的完全相同的 DOT 源。
digraph test {
a [color=red]
b [color=red]
c [color=red]
d
e
f
g
m
n
a -> d
d -> g
g -> m
m -> n
b -> e
b -> f
e -> n
c -> f
{
rank=same
a
b
c
}
}
我一直在寻找在 python 的 graphviz 中指定图形中节点位置的方法。我在点中找到了 rank command 的子图,这正是我要找的,但我找不到在 python 中将子图和 graphviz 中的等级结合起来的方法。我也尝试强制节点位置,但也没有用。我创建了一个我想要实现的简单示例。
这是我的代码:
from graphviz import Digraph
top_nodes = ['a', 'b', 'c']
other_nodes = ['d', 'e', 'f', 'g', 'm', 'n']
g = Digraph('test', format='png')
for n in top_nodes:
g.node(str(n), color='red')
for n in other_nodes:
g.node(str(n))
g.edge('a', 'd')
g.edge('d', 'g')
g.edge('g', 'm')
g.edge('m', 'n')
g.edge('b', 'e')
g.edge('b', 'f')
g.edge('e', 'n')
g.edge('c', 'f')
g.view()
这是输出:
我希望红色节点('sources')在同一层级的图形顶部,只要保留层次布局,其余节点的位置并不那么重要。
尝试 rank = same 语句
digraph G {
a b c d e f g m n
{rank = same; a; b; c;}
a->d
d->g
g->m
m->n
b->e
b->f
e->n
c->f
}
我遇到了同样的问题,发现使用子图解决了问题。
from graphviz import Digraph
top_nodes = ['a', 'b', 'c']
other_nodes = ['d', 'e', 'f', 'g', 'm', 'n']
g = Digraph('test', format='png')
s = Digraph('subgraph')
s.graph_attr.update(rank='min')
for n in top_nodes:
s.node(str(n), color='red')
for n in other_nodes:
g.node(str(n))
g.edge('a', 'd')
g.edge('d', 'g')
g.edge('g', 'm')
g.edge('m', 'n')
g.edge('b', 'e')
g.edge('b', 'f')
g.edge('e', 'n')
g.edge('c', 'f')
g.subgraph(s)
g.view()
image output
从你的代码开始,使用子图上下文就足够了,只需添加
with g.subgraph() as s:
s.attr(rank = 'same')
for n in top_nodes: s.node(n)
这似乎比显式声明子图并将其添加到原始图更容易。
顺便说一句,此解决方案生成与 @RaHo 答案中的完全相同的 DOT 源。
digraph test {
a [color=red]
b [color=red]
c [color=red]
d
e
f
g
m
n
a -> d
d -> g
g -> m
m -> n
b -> e
b -> f
e -> n
c -> f
{
rank=same
a
b
c
}
}