问题描述
我正在使用python3的anytree包从列表["abc", "abd", "aec", "add", "adcf"]
创建树.在此树中,每个列表元素的第一个字符-a
是一个根,随后,其他字符被添加为其子元素.当我渲染树时,它看起来像:
I am creating a tree from a list ["abc", "abd", "aec", "add", "adcf"]
using anytree package of python3. In this tree first character of each list element - a
is a root, and subsequently, other characters are added as their children. When I render tree it looks like:
a
├── b
│ ├── c
│ └── d
├── e
│ └── c
└── d
├── d
└── c
└── f
但是当我使用to_picture
方法将树渲染为图片时,图像为-
But when I render the tree to picture using to_picture
method, the image is -
我不希望合并公共节点,因为它会将不必要的路径添加到我的树中.
I don't want the common nodes to be merged, as it is adding unwanted paths to my tree.
推荐答案
graphviz
中的节点使用其ID进行排列.在您的情况下,仅使用节点名称生成图形,然后graphviz
在获得图形时创建回路边.
The node are arranged in graphviz
using their id. In your case the graph is generated with just node names and then graphviz
created the loop edge as you get it.
对于每个节点,您真正想要的是不同的id
,并且与此节点相关联的label
. DotExporter
类具有名为nodeattrfunc
的属性,我们可以向其中传递函数或lambda并为节点生成属性
What you really want is different id
for each node and a label
associated with the same. The DotExporter
class has a attribute named nodeattrfunc
to which we can pass a function or a lambda and generate attributes for the nodes
以下是基于数组的处理方式
Below is how you would do it based on your array
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";
}
以及下图
这篇关于使用anytree和graphviz在python中渲染树,而不合并公共节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!