Reputation: 3231
I am using Python on Mac OSX Leopard.
I am trying to run the program 'dot' (part of Graphviz) from Python:
# -*- coding: utf-8 -*-
import os
print os.environ['PATH']
print os.system("ls >> a.txt")
print os.system("dot -o9.png -Tpng ./6.dot")
The command "ls" is there just to make sure that python is in the correct directory. It is. The result that I get is:
/usr/bin:/bin:/usr/sbin:/sbin 0 32512
My understanding is that 32512 error means that python could not find the file, and since the file 6.dot is there (If I run "dot -o9.png -Tpng ./6.dot" from the terminal I receive no error, and 9.png gets produced), I assume Python can't find the dot file.
I probably need to add the dot file to the path. But I don't know where is it. If I run:
whereis dot
I receive no answer.
How can I find the dot executable?
Alternatively, can I run the dot program as a command from inside Python?
Upvotes: 6
Views: 10661
Reputation: 1689
If you are using a GUI such as Spyder
then you can simply add the correct bin path into the PYTHONPATH manager
options menu.
Search for the script location by doing this in the terminal:
which programname
then take that location (wherever it is), subtract the programname, for example:
/home/username/seiscomp3/bin/scart
#this is the section of the path that you use
/home/username/seiscomp3/bin
Then go into the PYTHONPATH manager
options menu and add this path. Then restart Spyder and it'll work.
Upvotes: 0
Reputation: 21323
Try this:
# -*- coding: utf-8 -*-
import os
import sys
print os.environ['PATH']
os.environ['PATH'] += ":"+"/usr/local/bin"
print os.environ['PATH']
print os.getcwd()
from subprocess import check_call
print check_call(["dot", "-o9.png", "-Tpng", "./6.dot"])
Taken from the question to try and maintain some sort of sanity here.
Upvotes: 3
Reputation: 12349
One problem is in this line:
os.environ['PATH'] += ":"+"/usr/local/bin/dot"
You don't put the name of the executable in the path, but the directory containing the executable. So that should be:
os.environ['PATH'] += ":"+"/usr/local/bin"
And as pointed out in another comment, the arguments to check_call
are not the same as os.system
.
Upvotes: 1
Reputation: 7717
check_call
does not use the same syntax as os.system
, so you should try changing the corresponding line this way:
print check_call(["dot", "-o9.png", "-Tpng", "./6.dot"])
The executable name is the first item in the array, and each parameter must be in another item of the array. Otherwise you will always get a "No such file" error because there is no executable named "dot -o9.png ..." in your PATH.
Upvotes: 1
Reputation: 5104
You should change the PATH line so it includes the directory which contains dot
. That directory is /usr/local/bin
, without /dot
.
Upvotes: 2
Reputation: 2960
Two suggestions
Change this
os.environ['PATH'] += ";"+"/usr/local/bin/dot"
to this
os.environ['PATH'] += ":"+"/usr/local/bin"
Then your good.
EDIT: Note that I forgot to remove the /dot from the PATH variable myself (oops) - PATH is a colon delimited list of directories.
Upvotes: 2
Reputation: 1460
Instead of:
print os.system("dot -o9.png -Tpng ./6.dot")
try this:
from subprocess import check_call
print check_call("dot -o9.png -Tpng ./6.dot")
If exit status of dot program is 0, the status is printed. If dot returns non-zero status, it raises CalledProcessError (and shows returned status). If dot doesn't exist in current path, OSError is raised on Linux or WindowsErroor on Windows (I don't know which exception is raised under Mac OS, but I assume OSError).
EDIT: Code above will give you the hint if you have no dot executable or 6.dot file in current path settings.
Upvotes: 1
Reputation: 1302
Often the solution is in front of us,
print os.system("/usr/local/bin/dot -o9.png -Tpng 6.dot")
Also you can try for all the dots in a specified folder
import glob
for filedot in glob.glob('*.dot')
print os.system("/usr/local/bin/dot -o9.png -Tpng %(filedot)s"%locals())
#print os.system("/usr/local/bin/dot -o9.png -Tpng %s"%filedot)
Edit:
I cannot recall btw if it is
/usr/local/bin/dot -o9.png -Tpng fdot.dot
or
/usr/local/bin/dot -o 9.png -Tpng fdot.dot
Upvotes: 2
Reputation: 2857
If you also generate your Dot files in Python, pydot does what you want in a more Pythonic way:
import pydot
dot = pydot.Dot()
n1, n2 = pydot.Node("a"), pydot.Node("b")
dot.add_node(n1)
dot.add_node(n2)
dot.add_edge(pydot.Edge(n1,n2))
dot.write_png("graph.png", prog='neato')
Upvotes: 2
Reputation: 100914
Troubleshooting tips:
A. add
print os.getcwd()
on the line before os.system("dot etc.
Just to make sure that the current directory is the one with the 6.dot
file.
B. Make sure that the dot
program is in your path.
which dot
C. Use the full path to the dot
program in your os.system command, see what happens then.
Upvotes: 2
Reputation: 6341
You need to add the path to the 'dot' executable in Python's environment. You can do this by modifying the PATH variable in os.environ
Upvotes: 3
Reputation: 152927
whereis
locates man pages, which
locates binaries. So try which dot
.
Upvotes: 10