45

I have a dot file generated from my code and want to render it in my output. For this i have seen on the net that the command is something like this on cmd

dot -Tpng InputFile.dot -o OutputFile.png  for Graphviz

But my problem is that I want to use this inbuilt in my python program.

How can i do so ??

I looked at pydot but can't seem to find an answer in there.....

Sam
  • 110
  • 1
  • 1
  • 8

9 Answers9

68

Load the file with pydot.graph_from_dot_file to get a pydot.Dot class instance. Then write it to a PNG file with the write_png method.

import pydot

(graph,) = pydot.graph_from_dot_file('somefile.dot')
graph.write_png('somefile.png')
0 _
  • 10,524
  • 11
  • 77
  • 109
Judge Maygarden
  • 26,961
  • 9
  • 82
  • 99
  • 2
    This works like a charm, but let me ask a (silly) question: why does it work with `(graph, ) = pydot...` but not with `graph = pydot...` (I get `AttributeError: 'list' object has no attribute 'write_png')`? – pepa.dvorak May 08 '18 at 22:24
  • 1
    "TypeError: 'Dot' object is not iterable". I got the above error for the line "(graph,) = pydot.graph_from_dot_file('somefile.dot')". why am i getting this error and how do i fix this? – bananagator Jul 02 '18 at 17:53
  • 3
    I am using exactly this but I get an issue saying `[Errno 2] "dot" not found in path.` – Guilherme Felipe Reis Feb 15 '19 at 12:53
  • 1
    @GuilhermeFelipeReis That sounds like a GraphViz configuration issue. Do you have GraphViz `dot` installed? Is it in your PATH environment variable? https://graphviz.gitlab.io/download/ – Judge Maygarden Feb 21 '19 at 16:48
  • @JudgeMaygarden it was missing the binary, so I added `apk add --update --no-cache graphviz` – Guilherme Felipe Reis Feb 21 '19 at 16:55
  • 3
    I'm also facing `"dot" not found in path.` and I have it in the PATH environment variable. I can run `dot` in Anaconda Prompt. – Alisson Reinaldo Silva Mar 01 '19 at 14:43
28

pydot needs the GraphViz binaries to be installed anyway, so if you've already generated your dot file you might as well just invoke dot directly yourself. For example:

from subprocess import check_call
check_call(['dot','-Tpng','InputFile.dot','-o','OutputFile.png'])
Mark Longair
  • 446,582
  • 72
  • 411
  • 327
6

You can use pygraphviz. Once you have a graph loaded, you can do

graph.draw('file.png')
nmichaels
  • 49,466
  • 12
  • 107
  • 135
4

You can try:

import os
os.environ["PATH"] += os.pathsep + 'C:/Program Files (x86)/Graphviz2.38/bin/'
os.system('dot -Tpng random.dot -o random.png')
Ashok Kumar Jayaraman
  • 2,887
  • 2
  • 32
  • 40
  • The OP specifically asked for code that is "inbuilt in my python program", implying a preference for an answer that does not depend on an external command. You also have written non-portable Windows code that relies on a specific version and installation directory for Graphviz. – Captain Lepton Apr 08 '19 at 11:29
  • Invoking a subshell is an extremely poor practice from a security standpoint as it creates a command injection attack vector, and should be avoided at all cost. – CervEd Apr 11 '19 at 09:19
  • https://github.com/pydot/pydot/blob/48ba231b36012c5e13611807c9aac7d8ae8c15c4/pydot.py#L129 – joefromct Jul 25 '19 at 19:52
4

You can use graphviz:

# Convert a .dot file to .png
from graphviz import render
render('dot', 'png', 'fname.dot')

# To render an existing file in a notebook
from graphviz import Source
Source.from_file("fname.dot")
Sam Perry
  • 2,554
  • 3
  • 28
  • 29
4

1st Solution)

Going further with the approach of @Mauricio Carrero by setting the PATH inside the script (the same PATH set in the environment variables does not have this effect!):

import os
import pydotplus
from sklearn.tree import export_graphviz

os.environ['PATH'] = os.environ['PATH']+';' + r'C:\Users\Admin\Anaconda3\Library\bin\graphviz'

# first export the dot file only if needed
export_graphviz(clf, out_file=filename + ".dot", feature_names = feature_names)
# now generate the dot_data again
dot_data = export_graphviz(clf, out_file=None, feature_names = feature_names)
graph = pydotplus.graphviz.graph_from_dot_data(dot_data)
graph.write_png(filename + "_gv.png")

This made it possible to save the dot_data to png. Choose your own local paths, you might also have installed graphviz in `C:/Program Files (x86)/Graphviz2.38/bin/

This solution also came from Sarunas answer here: https://datascience.stackexchange.com/questions/37428/graphviz-not-working-when-imported-inside-pydotplus-graphvizs-executables-not

2nd Solution)

You can also avoid the error

Exception has occurred: InvocationException
GraphViz's executables not found

by simply giving it what it wants, as it asks for the executables of the graphviz object:

graph = pydotplus.graphviz.graph_from_dot_data(dot_data)
# graph is now a new Dot object!
# That is why we need to set_graphviz_executables for every new instance
# This cannot be set globally but must be set again and again
# that is why the PATH solution (1st Solution) above seems much better to me
# see the docs in https://pydotplus.readthedocs.io/reference.html
pathCur = 'C:\\Program Files (x86)\\Graphviz2.38\\bin\\'
graph.set_graphviz_executables({'dot': pathCur+'dot.exe', 'twopi': pathCur +'twopi.exe', 'neato': pathCur+'neato.exe', 'circo': pathCur+'circo.exe', 'fdp': pathCur+'fdp.exe'})
graph.write_png(filename + "_gv.png")

p.s: These 2 approaches were the only solutions working for me after 2 hours of calibrating erroneuos installations and full uninstall and install again, all varieties of PATH variables, external and internal graphviz installation, python-graphviz, pygraphviz and all of the solutions I could find in here, or in Convert decision tree directly to png or in https://datascience.stackexchange.com/questions/37428/graphviz-not-working-when-imported-inside-pydotplus-graphvizs-executables-not?newreg=a789aadc5d4b4975949afadd3919fe55

For conda python-graphviz, I got constant installation errors like

InvalidArchiveError('Error with archive C:\\Users\\Admin\\Anaconda3\\pkgs\\openssl-1.1.1d-he774522_20ffr2kor\\pkg-openssl-1.1.1d-he774522_2.tar.zst.  You probably need to delete and re-download or re-create this file.  Message from libarchive was:\n\nCould not unlink')

For conda install graphviz, I got

InvalidArchiveError('Error with archive C:\\Users\\Admin\\Anaconda3\\pkgs\\openssl-1.1.1d-he774522_21ww0bpcs\\pkg-openssl-1.1.1d-he774522_2.tar.zst.  You probably need to delete and re-download or re-create this file.  Message from libarchive was:\n\nCould not unlink')

pygraphviz needs MS Visual C++ which I did not want to install:

error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools": https://visualstudio.microsoft.com/downloads/

In the end, no guide was working to really set the PATH variables correctly except for the 1st Solution approach.

questionto42
  • 7,175
  • 4
  • 57
  • 90
1

Here is the code that worked for me on windows 11 system using a pycharm terminal using venv python 3.8 interpreter.

from graphviz import render
import os
os.environ['PATH'] = os.environ['PATH']+';' + r"C:\Program Files\Graphviz\bin" #find binaries of graphviz and add to path
render('dot','png','classes.dot')

this will create a classes.dot.pg file (I don't know how to fix the name but this is a png file you can open)

The classes dot was generated on terminal using

pyreverse package_path

pyreverse comes with pylint.

Installations:

pip install pylint

(install pylint only if you are creating classes.dot file)

pip install graphviz

0

This would create a graph 'a' to 'b' and save it as a png file.

code:

from graphviz import Digraph

dot = Digraph()
dot.node('a')
dot.node('b')
dot.edge('a','b')

dot. Render("sample.png")
pyComali
  • 44
  • 6
-2
from graphviz import render
dot.render(directory='doctest-output', view=True)
cottontail
  • 10,268
  • 18
  • 50
  • 51
Dave
  • 1
  • 1