我正在使用python3的anytree包从列表["abc", "abd", "aec", "add", "adcf"]
创建一个树。在此树中,每个列表元素的第一个字符 - a
是根,随后,其他字符将作为其子项添加。当我渲染树时,它看起来像:
a
├── b
│ ├── c
│ └── d
├── e
│ └── c
└── d
├── d
└── c
└── f
但是当我使用to_picture
方法将树渲染到图片时,图像是 -
我不希望合并公共节点,因为它会向我的树添加不需要的路径。
答案 0 :(得分:7)
节点使用其ID在graphviz
中排列。在您的情况下,图表仅使用节点名称生成,然后graphviz
创建循环边缘。
您真正想要的是每个节点不同的id
和与之相关的label
。 DotExporter
类有一个名为nodeattrfunc
的属性,我们可以向其传递函数或lambda并为节点生成属性
以下是基于数组
的方法import anytree
from anytree import Node, RenderTree
data = ["abc", "abd", "aec", "add", "adcf"]
from anytree.exporter import DotExporter
nodes = {}
first_node = None
for elem in data:
parent_node = None
parent_node_name = ""
for i, val in enumerate(elem):
if i not in nodes:
nodes[i] = {}
key = parent_node_name + val
if key not in nodes[i]:
print("Creating new node for ", key)
nodes[i][key] = Node(key, parent=parent_node, display_name=val)
if first_node is None:
first_node = nodes[i][key]
parent_node = nodes[i][key]
parent_node_name = val
print(nodes)
DotExporter(nodes[0]["a"],
nodeattrfunc=lambda node: 'label="{}"'.format(node.display_name)).to_dotfile("graph.txt")
DotExporter(nodes[0]["a"],
nodeattrfunc=lambda node: 'label="{}"'.format(node.display_name)).to_picture("graph.png")
这将生成以下点文件
digraph tree {
"a" [label="a"];
"ab" [label="b"];
"bc" [label="c"];
"bd" [label="d"];
"ae" [label="e"];
"ec" [label="c"];
"ad" [label="d"];
"dd" [label="d"];
"dc" [label="c"];
"cf" [label="f"];
"a" -> "ab";
"a" -> "ae";
"a" -> "ad";
"ab" -> "bc";
"ab" -> "bd";
"ae" -> "ec";
"ad" -> "dd";
"ad" -> "dc";
"dc" -> "cf";
}
以下图表
答案 1 :(得分:0)
由于anytree
to_picture()
函数使用graphviz生成文件。
从SQL FIDDLE开始,您可以阅读:
graphviz使用节点ID作为标签。如果不同的节点需要具有相同的标签,则必须明确定义标签。