pyinstall and matplotlib
Russell E. Owen
rowen at cesmail.net
Wed Feb 13 13:07:29 EST 2008
In article
<3144e444-3542-4550-a280-ff15da8bed0b at l16g2000hsh.googlegroups.com>,
John Henry <john106henry at hotmail.com> wrote:
> On Feb 9, 2:53 pm, John Henry <john106he... at hotmail.com> wrote:
> > Has anybody been able to create an exe of their python applications
> > involving matplotlib using pyinstall (ver 1.3)? I am getting a:
> >
> > RuntimeError: Could not find the matplotlib data files
> >
> > when I attempt to run the exe created.
> >
> > In searching the web, it appears this is an issue when others tried to
> > use py2exe as well. Unfortunately, the few hits I saw doesn't include
> > enough details to inspire me as to what I should be doing in my
> > pyinstall .spec file.
> >
> > Does anybody has an example or information about this?
> >
> > Thanks,
>
> Well, looks like nobody has an answer to this question.
>
> How'bout py2exe or other ways of creating exe files out of matplotlib
> projects? Has anybody been able to do that? (I am cross-posting
> these messages to the matploblib mailing list).
For py2exe I have appended a setup script I use to bundle an application
that includes matplotlib. I am no Windows expert and there are probably
better ways to do it, but it does work. I have made no attempt to strip
out extra stuff.
(As for pyinstaller:a year or so ago I tried to use it to make a bundled
*unix* version of my app. If that had worked I'd have considered trying
to use it for Windows as well. But after a lot of experimenting I was
never able to get anything even close to functional. Maybe it's better
now.)
-- Russell
from distutils.core import setup
import os
import sys
import matplotlib
import py2exe
# The following code is necessary for py2exe to find win32com.shell.
# Solution from
<http://starship.python.net/crew/theller/moin.cgi/WinShell>
import win32com
import py2exe.mf as modulefinder
for pth in win32com.__path__[1:]:
modulefinder.AddPackagePath("win32com", pth)
for extra in ["win32com.shell"]:
__import__(extra)
m = sys.modules[extra]
for pth in m.__path__[1:]:
modulefinder.AddPackagePath(extra, pth)
tuiRoot = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
roRoot = os.path.join(tuiRoot, "ROPackage")
sys.path = [tuiRoot, roRoot] + sys.path
import TUI.Version
mainProg = os.path.join(tuiRoot, "runtui.py")
NDataFilesToPrint = 0 # number of data files to print, per directory
def addDataFiles(dataFiles, fromDir, toSubDir=None,
inclHiddenDirs=False):
"""Find data files and format data for the data_files argument of
setup.
In/Out:
- dataFiles: a list to which is appended zero or more of these
elements:
[subDir, list of paths to resource files]
Inputs:
- fromDir: path to root directory of existing resource files
- toSubDir: relative path to resources in package;
if omitted then the final dir of fromDir is used
- inclHiddenDirs: if True, the contents of directories whose names
start with "." are included
Returns a list of the following elements:
"""
lenFromDir = len(fromDir)
if toSubDir == None:
toSubDir = os.path.split(fromDir)[1]
for (dirPath, dirNames, fileNames) in os.walk(fromDir):
if not inclHiddenDirs:
numNames = len(dirNames)
for ii in range(numNames-1, -1, -1):
if dirNames[ii].startswith("."):
del(dirNames[ii])
if not dirPath.startswith(fromDir):
raise RuntimeError("Cannot deal with %r files; %s does not
start with %r" %\
(resBase, dirPath, fromDir))
toPath = os.path.join(toSubDir, dirPath[lenFromDir+1:])
filePaths = [os.path.join(dirPath, fileName) for fileName in
fileNames]
dataFiles.append((toPath, filePaths))
# Add resources
dataFiles = []
# TUI resources
for resBase in ("Help", "Scripts", "Sounds"):
toSubDir = os.path.join("TUI", resBase)
fromDir = os.path.join(tuiRoot, toSubDir)
addDataFiles(dataFiles, fromDir, toSubDir)
# RO resources
for resBase in ("Bitmaps",):
toSubDir = os.path.join("RO", resBase)
fromDir = os.path.join(roRoot, toSubDir)
addDataFiles(dataFiles, fromDir, toSubDir)
# Add tcl snack libraries
pythonDir = os.path.dirname(sys.executable)
snackSubDir = "tcl\\snack2.2"
snackDir = os.path.join(pythonDir, snackSubDir)
addDataFiles(dataFiles, snackDir, snackSubDir)
# Add matplotlib's data files.
matplotlibDataPath = matplotlib.get_data_path()
addDataFiles(dataFiles, matplotlibDataPath, "matplotlibdata")
if NDataFilesToPrint > 0:
print "\nData files:"
for pathInfo in dataFiles:
print pathInfo[0]
nFiles = len(pathInfo[1])
for resPath in pathInfo[1][0:NDataFilesToPrint]:
print " ", resPath
if nFiles > NDataFilesToPrint:
print " ...and %d more" % (nFiles - NDataFilesToPrint)
versDate = TUI.Version.VersionStr
appVers = versDate.split()[0]
distDir = "TUI_%s_Windows" % (appVers,)
inclModules = [
# "email.Utils", # needed for Python 2.5.0
]
# packages to include recursively
inclPackages = [
"TUI",
"RO",
"matplotlib",
"dateutil", # required by matplotlib
"pytz", # required by matplotlib
# "matplotlib.backends",
# "matplotlib.numerix",
# "encodings",
# "numpy",
# "email", # needed for Python 2.5
]
setup(
options = dict(
py2exe = dict (
dll_excludes = [
# the following are for matplotlib 0.87:
"libgdk_pixbuf-2.0-0.dll",
"libgobject-2.0-0.dll",
"libgdk-win32-2.0-0.dll",
"wxmsw26uh_vc.dll",
],
excludes = [ # modules to exclude
"_gtkagg",
"_wxagg",
],
#includes = inclModules,
packages = inclPackages,
)
),
windows=[ # windows= for no console, console= for console
dict(
script = mainProg,
dest_base = "TUI",
icon_resources = [(1, "TUI.ico")],
),
],
data_files = dataFiles,
)
# rename dist to final directory name
os.rename("dist", distDir)
More information about the Python-list
mailing list