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.
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")
This will generate the below dot file
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";
}
And the below graph
