pyinstall and matplotlib

John Henry john106henry at hotmail.com
Thu Feb 14 14:17:17 EST 2008


Thank you for the response.  I am having trouble using the script.  I
am assuming the TUI is the application this script was developed for
and did my best to replace that with the name of my own.

To make things simple, let's say we take one of the sample matplotlib
program MULTICOLOR.PY and place that in a directory by itself.  I have
attached the modified script below. Notice that I commented out the
"import TUI.Version" and replaced TUI.Version.VersionStr with some
arbitrary number.  I have to create a directroy "dest" before running
it.

When I run this script, there is no error message.  Just:

running install
running build
running install_data

and then there is an empty directory "MULTICOLOR_2.31_Windows" created
and then nothing else.

#=================================
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, "multicolor.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("MULTICOLOR", 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 = "2.31" # TUI.Version.VersionStr
appVers = versDate.split()[0]
distDir = "MULTICOLOR_%s_Windows" % (appVers,)

inclModules = [
#    "email.Utils", # needed for Python 2.5.0
]
# packages to include recursively
inclPackages = [
    "MULTICOLOR",
    "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 = "MULTICOLOR",
            icon_resources = [(1, "python.ico")],
        ),
    ],
    data_files = dataFiles,
)

# rename dist to final directory name
os.rename("dist", distDir)



On Feb 13, 10:07 am, "Russell E. Owen" <ro... at cesmail.net> wrote:
> In article
> <3144e444-3542-4550-a280-ff15da8be... at l16g2000hsh.googlegroups.com>,
>  John Henry <john106he... 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