cx_Freeze executable not displaying matplotlib figures

浪尽此生 提交于 2019-12-11 16:55:39

问题


I am using Python 3.5 and I was able to create an executable using cx_Freeze but whenever I try to run the executable it runs without error but it cannot display any matplotlib figure. I have used Tkinter for my GUI. I have tried putting matplotlib backend as tkinter but figures are still not displaying.I cannot share the whole code as it is huge. Kindly Help.


回答1:


The following example adapted from the matplotlib example Embedding In Tk and from the cx_Freeze sample Tkinter works for my configuration (python 3.6, matplotlib 2.2.2, numpy 1.14.3+mkl, cx_Freeze 5.1.1 on Windows 7).

Main script main.py:

import tkinter

from matplotlib.backends.backend_tkagg import (
    FigureCanvasTkAgg, NavigationToolbar2Tk)
# Implement the default Matplotlib key bindings.
from matplotlib.backend_bases import key_press_handler
from matplotlib.figure import Figure

import math


root = tkinter.Tk()
root.wm_title("Embedding in Tk")

# Data for plotting
i = range(0, 300)
t = [_i / 100. for _i in i]
s = [2. * math.sin(2. * math.pi * _t) for _t in t]

fig = Figure(figsize=(5, 4), dpi=100)
fig.add_subplot(111).plot(t, s)

canvas = FigureCanvasTkAgg(fig, master=root)  # A tk.DrawingArea.
canvas.draw()
canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1)

toolbar = NavigationToolbar2Tk(canvas, root)
toolbar.update()
canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1)


def on_key_press(event):
    print("you pressed {}".format(event.key))
    key_press_handler(event, canvas, toolbar)


canvas.mpl_connect("key_press_event", on_key_press)


def _quit():
    root.quit()     # stops mainloop
    root.destroy()  # this is necessary on Windows to prevent Fatal Python Error: PyEval_RestoreThread: NULL tstate


button = tkinter.Button(master=root, text="Quit", command=_quit)
button.pack(side=tkinter.BOTTOM)

tkinter.mainloop()
# If you put root.destroy() here, it will cause an error if the window is closed with the window manager.

Setup script setup.py:

import sys
from cx_Freeze import setup, Executable
import os.path

PYTHON_INSTALL_DIR = os.path.dirname(os.path.dirname(os.__file__))
os.environ['TCL_LIBRARY'] = os.path.join(PYTHON_INSTALL_DIR, 'tcl', 'tcl8.6')
os.environ['TK_LIBRARY'] = os.path.join(PYTHON_INSTALL_DIR, 'tcl', 'tk8.6')

options = {
    'build_exe': {
        'include_files': [
            (os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tk86t.dll'), os.path.join('lib', 'tk86t.dll')),
            (os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tcl86t.dll'), os.path.join('lib', 'tcl86t.dll'))
         ],
        'packages': ['numpy']
    },
}

base = None
if sys.platform == 'win32':
    base = 'Win32GUI'

executables = [
    Executable('main.py', base=base)
]

setup(name='matplotlib_embedding_in_Tkinter',
      version='0.1',
      description='Sample cx_Freeze matplotlib embedding in Tkinter script',
      options=options,
      executables=executables
      )

Explanations:

  • In order to freeze an application using Tkinter with cx_Freeze, one needs to set the TCL and TK library environment variables in the setup script, and to tell cx_Freeze to include the corresponding DLLs, see KeyError: 'TCL_Library' when I use cx_Freeze. The solution described there needs to be adapted when using cx_Freeze 5.1.1, see Getting "ImportError: DLL load failed: The specified module could not be found" when using cx_Freeze even with tcl86t.dll and tk86t.dll added in.
  • numpy is required by matplotlib and it needs to be included in the frozen application even if the application itself does not explicitly use numpy. In order to include numpy in an application frozen with cx_Freeze, one needs to add numpy to the packages list of the build_exe option in the setup script, see Creating cx_Freeze exe with Numpy for Python.


来源:https://stackoverflow.com/questions/53058817/cx-freeze-executable-not-displaying-matplotlib-figures

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!