使用anytree和graphviz在python中渲染树,而不合并公共节点

Him*_*dri 4 graphviz python-3.x anytree

我正在["abc", "abd", "aec", "add", "adcf"]使用任何python3包创建一个列表中的树.在这个树中,每个列表元素的第一个字符 - a是一个根,随后,其他字符被添加为它们的子元素.当我渲染树时,它看起来像:

to_picture

但是当我使用["abc", "abd", "aec", "add", "adcf"]方法将树渲染到图片时,图像是 -

在此输入图像描述

我不希望合并公共节点,因为它向我的树添加了不需要的路径.

提前致谢.

Tar*_*ani 8

节点graphviz使用它们的id 排列.在您的情况下,图表仅使用节点名称生成,然后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")
Run Code Online (Sandbox Code Playgroud)

这将生成以下点文件

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";
}
Run Code Online (Sandbox Code Playgroud)

以下图表

最终图表