py2exe: matplotlib
5 Luglio 2011
Avendo a che fare con matplotlib, ho avuto parecchi problemi a configurare il setup di py2exe.
Grazie alla doc ufficiale di py2exe con qualche piccolo accorgimento, sono
riuscito a fare il freeze della mia applicazione.
Riassumo il tutto estrapolando solo la parte inerente Matplotlib:
'''Module for HistoGram creation''' import numpy as np import matplotlib matplotlib.use('wxagg') # backend import matplotlib.pyplot as plt class Bars(object): '''Crea un istogramma in base ai dati in ingresso: possono essere di tipo dict(nome: valore) o di tipo list, con il formato tipico del metodo fetchall() d sqlite3 ''' def __init__(self, data): self.data = data self.dict_data = {} print "HISTO > Loading data... ", self.data for item in self.data: self.dict_data[item[0]] = (item[1]) try: n_bars = len(self.dict_data) pts = self.dict_data.values() teams = self.dict_data.keys() ind = np.arange(n_bars) # the x locations for bar width = 0.2 # the width of the bars plt.subplot(111) bars = plt.bar(ind + 0.2, pts, width, color='b', align = 'center') plt.title('Classifica') plt.ylabel('pts') plt.xticks(ind + width , teams, size = 'x-small', rotation = 15) for vbar in bars: val = float(vbar.get_height()) x_pos = vbar.get_x() + 0.4 y_pos = vbar.get_height() - 0.1 * vbar.get_height() plt.text(x_pos, y_pos, '%.1f'%val, ha='center', va='bottom', size = 'small', rotation = 90) plt.show() except AttributeError: print "Grafico non rappresentabile, controllare dato in ingresso" def main(): '''app starter''' data = [('Boy SAN', 100), ('Cioppersson', 105), ('Stella Blu Kativeria', 120), ('Pippo', 180), ('MiddleSboron', 98), ('Nizzi', 140), ('F.C.Zipangolo', 165), ('Real Ancona', 135), ('Gnagna', 88), ('Cento', 98)] Bars(data) if __name__ == '__main__': main()
Dal solito sample del setup di py2exe:
#!/usr/bin/python """py2exe custom setup Sample author: bancaldo""" import py2exe, sys, wx, os, glob import matplotlib from distutils.core import setup if len(sys.argv) == 1: sys.argv.append("py2exe") sys.argv.append("-q") class FileBrowser(wx.FileDialog): '''Class for file browser''' def __init__(self): self.fin = None wildcard = "File di testo (*.py)|*.py|" "Tutti i files (*.*)|*.*" wx.FileDialog.__init__(self, None, "scegli il file", os.getcwd(), "", wildcard, wx.OPEN | wx.CHANGE_DIR) if self.ShowModal() == wx.ID_OK: print(self.GetPath()) self.file = self.GetPath() self.fin = open(self.file, 'r') else: print "operazione apertura annullata" self.Destroy() self.Destroy() class Target(object): '''Terget''' def __init__(self, **kw): self.__dict__.update(kw) # info di versione self.version = "1.0.0" self.company_name = "Bancaldo TM" self.copyright = "no copyright" self.name = "py2exe sample files" def main(): '''py2exe setup starter''' app = wx.PySimpleApp() app.MainLoop() manifest_template = ''' <?xml version='1.0' encoding='UTF-8' standalone='yes'?> <assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'> <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> <security> <requestedPrivileges> <requestedExecutionLevel level='asInvoker' uiAccess='false' /> </requestedPrivileges> </security> </trustInfo> <dependency> <dependentAssembly> <assemblyIdentity type='win32' name='Microsoft.VC90.CRT' version='9.0.21022.8' processorArchitecture='*' publicKeyToken='1fc8b3b9a1e18e3b' /> </dependentAssembly> </dependency> <dependency> <dependentAssembly> <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*" /> </dependentAssembly> </dependency> </assembly> ''' file_to_freeze = FileBrowser().file textentry = wx.TextEntryDialog(None, "nome file EXE?", '', '') if textentry.ShowModal() == wx.ID_OK: destname = textentry.GetValue() rt_manifest = 24 explicit_incl = ["sqlalchemy.dialects.sqlite.base", "matplotlib.backends.backend_wxagg",] other_res = [(rt_manifest, 1, manifest_template % dict(prog = "Fanta"))] setup_opts = {"py2exe": {"includes": explicit_incl, "compressed": 1, "optimize": 2, #"ascii": 1, "bundle_files": 1,}} test_wx = Target(description = "A GUI app", script = file_to_freeze, other_resources = other_res, icon_resources = [(1, "images\py.ico")], dest_base = destname) # images path = (os.getcwd() + "\images\") data_files = [('images', [png for png in glob.glob(path + '*.png')])] # matplotlib data_files.extend(matplotlib.get_py2exe_datafiles()) setup(data_files = data_files, # images options = setup_opts, zipfile = None, windows = [test_wx], ) if __name__ == '__main__': main()
focalizziamo le parti importanti relative a Matplotlib:
Innanzitutto importiamo Matplotlib all’interno del setup, per poter sfruttare
la funzione get_py2exe_datafiles(), che crea un lista con tutti i file
necessari da estendere alla lista data_files.
import matplotlib ... # images path = (os.getcwd() + "\images\") data_files = [('images', [png for png in glob.glob(path + '*.png')])] # matplotlib data_files.extend(matplotlib.get_py2exe_datafiles()) ...
come ultima cosa importantissima, negli “includes” espliciti da passare alle
opzioni di setup, dobbiamo aggiungere il backend utilizzato:
import matplotlib ... explicit_incl = ["sqlalchemy.dialects.sqlite.base", "matplotlib.backends.backend_wxagg",] ... setup_opts = {"py2exe": {"includes": explicit_incl, "compressed": 1, "optimize": 2, #"ascii": 1, "bundle_files": 1,}} ...
link:
il mio sample,
py2exe: MatplotLib
Categorie:py2exe
Commenti recenti