1

I'm trying to read a .dot file produced by sklearn.tree.export_to_graphviz into a graph using NetworkX. I plan to add this graph as a subplot in a pyplot graph. While I'm able to use nx.drawing.nx_pydot.read_dot to obtain the graph structure, all of the labels seem to disappear.

This is what I'm trying:

randTree = (nx.drawing.nx_pydot.read_dot("tree_output.dot"))
nx.draw_networkx(randTree)

The .dot file is:

digraph Tree {
node [shape=box] ;
0 [label="X[0] <= 332.72\nsamples = 19\nvalue = -0.41"] ;
1 [label="samples = 11\nvalue = -0.67"] ;
0 -> 1 [labeldistance=2.5, labelangle=45, headlabel="True"] ;
2 [label="X[0] <= 576.73\nsamples = 8\nvalue = -0.04"] ;
0 -> 2 [labeldistance=2.5, labelangle=-45, headlabel="False"] ;
3 [label="samples = 4\nvalue = -0.05"] ;
2 -> 3 ;
4 [label="samples = 4\nvalue = -0.03"] ;
2 -> 4 ;
}

What results is a graph with 4 circles labeled 1-4, without any other labels or properties (I imagine the box shape is a property of the node so that's why they're all circles), which is linked below. If there is another way to show this decision in a pyplot plot, I'd be happy to hear!

Resulting Graph

1 Answers1

0

Your issue isn't with nx.drawing.nx_pydot.read_dot, but with drawing the network. When reading the dot file the labels are kept, however you'll need to use NetworkX' drawing API a bit differently to draw the labels. For example:

import networkx as nx
import matplotlib.pyplot as plt
import ast

randTree = (nx.drawing.nx_pydot.read_dot('tree_output.dot'))
labels = {n[0] : ast.literal_eval(n[1]['label']) for n in randTree.nodes(data=True)}
nx.draw_networkx(randTree, with_labels=True, labels=labels)
plt.show()

Will draw:

enter image description here

Edit:

You can also convert the graph to a Graphviz AGraph and draw it as follows:

import networkx as nx

A = nx.drawing.nx_agraph.to_agraph(nx.drawing.nx_pydot.read_dot('tree_output.dot'))
A.layout('dot')
A.draw('tree.png')

Which will draw the following graph:

enter image description here

zohar.kom
  • 1,765
  • 3
  • 12
  • 28
  • 1
    Is there a way to take all of the properties (such as the box shape and the edge labels) from the .dot file and insert them into the NetworkX graph at the same time? Or is it a matter of pulling everything out feature by feature? – Kay Tukendorf Jan 30 '19 at 16:11
  • I thought you want to show your graph with matplotlib pyplot, and then you would have to convert it feature by feature (I've shown how to extract labels, positioning of nodes can be done with **layouts**, nodes' shape with **node_shape** parameter etc.). I edited the original answer to show how to visualize the graph with all graphviz properties from the input dot file. Hope it helps :) – zohar.kom Jan 30 '19 at 16:38
  • Unfortunately I'm using Windows which apparently isn't playing nice with pygraphviz so I can't take that solution which is ultimately what I'm trying to achieve :( – Kay Tukendorf Jan 30 '19 at 17:14
  • It can work on windows, maybe take a look here: https://stackoverflow.com/q/4571067/3782865 – zohar.kom Jan 30 '19 at 17:34