Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update docstring of function pydot.graph_from_dot_data #159

Closed
jrbrearley opened this issue Oct 6, 2017 · 5 comments
Closed

update docstring of function pydot.graph_from_dot_data #159

jrbrearley opened this issue Oct 6, 2017 · 5 comments
Assignees
Milestone

Comments

@jrbrearley
Copy link

There are a number of examples on the web that suggest pydot.graph_from_dot_data should create a pydot.Dot object, which has numerous write_xxx methods, including write_png & write_pdf. The stripped down code sample below shows that I get a list object, not at pydot.Dot object.

I am running WinPython 3.6.1 on Windows 7, Intel i7-4770S, 3.1GHz, 16GB RAM

The sample code starts with an sklearn classifier that correctly generates a digraph tree str class, which can be used to create a .Source graphviz object, which it turn will render a .png or .pdf file, no issues. This confirms that my graphviz installation is operational.

In the sample code, a pydot.Dot object does have the expected write_xxx methods. However, when the pydot.graph_from_dot_data function is used, these methods dont exist. My attempts at using add_subgraph to add the dot_data string didn't work out.

Written by John Brearley Oct 2017

Illustrates graphviz working OK, pydot has issues.

Create basic classifier object

import sklearn.tree
clf = sklearn.tree.DecisionTreeClassifier()

Learn the dummy training

train_data = [[0, 1], [2, 3]]
train_target = [0, 1]
clf=clf.fit(train_data, train_target)

Test the classifier with dummy test data

test_data = [[4, 5]]
results = clf.predict(test_data)
print ("results:",results,type(results))

Setup for visualization code

out_fn = "ML_ex2_pydot_issue"
fmt = "png"

Get data in digraph tree format, string class, for use in graphvviz.

feature_names = ["len", "wid"]
target_names = ["A", "B"]
dot_data = sklearn.tree.export_graphviz(clf,out_file=None,
feature_names=feature_names,class_names=target_names,filled=True,
rounded=True,impurity=False)
print("dot_data:", type(dot_data),dot_data)

Graphviz package requires a seperate install of the Graphviz software from http://graphviz.org

- if you dont do this, you get interesting errors from backend.py render function re ExecutableNotFound

- there is also a hint about your PATH variable needing something

- after you install Graphviz, you need to manually update PATH variable to add: C:\Program Files (x86)\Graphviz\bin

- a new instance of the DOS prompt window will show the updated PATH right away

- BUT the "WinPython Command Prompt.exe" wont update until you reboot your PC!!!

- from the command line, you should be able to type "dot.exe -V" to see version info

When we have preformatted graph data, use the Source class.

Graph & Digraph classes are used when you want to individually

add nodes, edges and other formatting.

import graphviz as gv
graph = gv.Source(dot_data, format=fmt) ;# load dot_data in one shot
print("graph.source:",graph.source) ;# shows graph raw data
gv_fn = graph.render(filename=out_fn)
print ("gv_fn:",gv_fn)

Video shows pydot making graphs.

print("\npydot graph")
from sklearn.externals.six import StringIO
dot_data2 = StringIO()
sklearn.tree.export_graphviz(clf,out_file=dot_data2,
feature_names=feature_names,class_names=target_names,filled=True,
rounded=True,impurity=False)
print("dot_data2.getvalue():",type(dot_data2.getvalue()),dot_data2.getvalue())

out_fn2 = out_fn+"_B.png"
print ("out_fn2:", out_fn2)

import pydot
graph2 = pydot.Dot(graph_type="digraph")
print ("graph2:",graph2,type(graph2))

sub_graph = pydot.Subgraph(dot_data2.getvalue())

y = pydot.graph_from_dot_data(dot_data2.getvalue())
print ("y:",y,type(y), str.join(" ",map(str,y)))
import sys
try:
y.write_png(out_fn2)
except:
print ("Error1:",sys.exc_info())

try:
graph2.add_subgraph(sub_graph)
# graph2.add_subgraph(y)
except:
print ("Error2:",sys.exc_info())

x = graph2.write_png(out_fn2)
print("x:",type(x),x)

@johnyf
Copy link
Contributor

johnyf commented Oct 6, 2017

The API has changed (f8d2b5e, 66734d2), and in pydot == 1.2.3 the function pydot.graph_from_dot_data returns a list of graphs in all cases. This applies also to dot_parser.parse_dot_data and pydot.graph_from_dot_file. Previously, a graph was returned in case of a singleton, and a list in case of multiple graphs, which was inhomogeneous.

The OP mentions examples outside of the pydot project, so they are not something to change in this repository. If the call is expected to return a single graph, you can get that graph with:

(g,) = pydot.graph_from_dot_data(s)

@jrbrearley
Copy link
Author

jrbrearley commented Oct 10, 2017 via email

@johnyf
Copy link
Contributor

johnyf commented Oct 14, 2017

Thanks for pointing out that the docstring is outdated, @jrbrearley. Update is needed here:

https://github.com/erocarrera/pydot/blob/35a8d858bd9da0b37268fe9b317fe4895387e75f/pydot.py#L228

and in any other functions that call dot_parser.parse_dot_data and have outdated docstrings.

@johnyf johnyf self-assigned this Oct 14, 2017
@johnyf
Copy link
Contributor

johnyf commented Oct 14, 2017

Relevant to #130.

@johnyf johnyf changed the title pydot.graph_from_dot_data not working per examples WinPython 3.6.1 update docstring of function pydot.graph_from_dot_data Oct 14, 2017
@johnyf
Copy link
Contributor

johnyf commented Oct 14, 2017

Addresses also #136, #149.

@johnyf johnyf added this to the 1.3.0 milestone Oct 14, 2017
@johnyf johnyf closed this as completed in 94c6d87 Dec 25, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants