11

I've been dealing with this for days now and hope to find some help. I developed a GUI-application with imported modules tkinter, numpy, scipy, matplotlib, which runs fine in python itself. After having converted to an exe everything works as expected, but NOT the matplotlib section. When I press my defined plot button, the exe simply closes and doesn't show any plots. So I thought to make a minimal example, where I simply plot a sin-function and I'm facing the same issue: Works perfect in python, when converting it to an exe it crashes when pressing the plot button. Here is the minimal example:

import tkinter as tk
import matplotlib.pyplot as plt
import numpy as np

class MainWindow(tk.Frame):
    def __init__(self):
        tk.Frame.__init__(self,bg='#9C9C9C',relief="flat", bd=10)
        self.place(width=x,height=y)
        self.create_widgets()

    def function(self):
        datax = np.arange(-50,50,0.1)
        datay = np.sin(datax)
        plt.plot(datax,datay)
        plt.show()

    def create_widgets(self):
        plot = tk.Button(self, text='PLOT', command=self.function)
        plot.pack()


x,y=120,300
root=tk.Tk()
root.geometry(str(x)+"x"+str(y))
app = MainWindow()
app.mainloop()

And here is my corresponding setup.py for converting with cx_Freeze:

import cx_Freeze
import matplotlib
import sys
import numpy
import tkinter

base = None

if sys.platform == "win32":
    base = "Win32GUI"

executables = [cx_Freeze.Executable("test.py", base=base)]


build_exe_options = {"includes":   ["matplotlib.backends.backend_tkagg","matplotlib.pyplot",
                             "tkinter.filedialog","numpy"],
                     "include_files":[(matplotlib.get_data_path(), "mpl-data")],
                     "excludes":[],
                    }

cx_Freeze.setup(
    name = "test it",
    options = {"build_exe": build_exe_options},
    version = "1.0",
    description = "I test it",
    executables = executables)

Any ideas that might solve the issue are highly appreciated. I'm working on a 64-bit Windows10 machine and I'm using the WinPython Distribution with Python 3.4.3.

jpeg
  • 2,372
  • 4
  • 18
  • 31
benellinger
  • 113
  • 1
  • 1
  • 8
  • It would be interesting to know if this issue is Windows 10 related, or if the same happens with other windows versions. – J.J. Hakala Jan 15 '16 at 08:16
  • Ah, sorry I forgot to mention it. The same issue happend with the same WinPython Distribution on a Windows 7, 64-bit machine. – benellinger Jan 15 '16 at 08:32
  • Just tried this on 32 bit XP with no problems, i'll try it on 64 bit win7 later – James Kent Jan 15 '16 at 09:47
  • Hello James, thanks for this information. Curious to hear what will be on your Win 7 system. I also tried Win 8, 64-bit and faced the same issue. – benellinger Jan 15 '16 at 18:13
  • There should be and error code popping up in the command prompt. Try opening the `exe` from command prompt, so it doesn't close right away and gives you time to read the error message. –  Jan 15 '16 at 22:39
  • Hi Delirious; thank you for the idea, I tried this but I've seen no error in the prompt. – benellinger Jan 16 '16 at 20:05
  • Tried to reinstall numpy it's doesn't work anyway. Solved by copy/past mkl_intel_thread.dll to root catalog of my app.exe – user3331901 Jun 14 '19 at 14:12

4 Answers4

35

I found a potential solution (or at least an explanation) for this problem while testing PyInstaller with the same test.py. I received error message about a dll file being missing, that file being mkl_intel_thread.dll.

I searched for that file and it was found inside numpy folder. I copied files matching mkl_*.dll and also libiomp5md.dll to the same directory where the test.exe created by python setup.py build was. After this the minimal test.exe showed the matplotlib window when pressing the plot button.

The files were located in folder lib\site-packages\numpy\core.

J.J. Hakala
  • 6,136
  • 6
  • 27
  • 61
  • That's amazing dude. I tried so many other things that, didn't work. But this works even for my complexer GUI and plotting. Wow, thanks so much !!! – benellinger Jan 20 '16 at 09:33
  • 6
    I'm using Anaconda and the DLL's aren't in the lib/site-packages/numpy/code folder. Instead I found them in Anaconda/Library/bin. – Matt Williams May 25 '16 at 01:27
  • How in the world did you know to also take libiomp5md.dll and not anything else? Can you maybe share your thought-process a little on that? It will help me if I get stuck on a similar problem in the future. This answer is like magic to me. I seriously didn't think it was going to work. My program is pretty complex. But your solution just plain works! – Frikster Oct 05 '16 at 02:52
  • @DirkHaupt It's been a while so I'm not sure if I remember correctly. I created a similar executable with Pyinstaller, and when running that executable a popup dialog informed what dll was missing. – J.J. Hakala Oct 06 '16 at 10:36
  • The same procedure works with nuitka and anaconda under Windows 10 – RobertaRavanelli May 18 '18 at 09:41
5

I really wanted to post this as a comment, but I don't have the reputation. This is mostly a followup to J.J. Hakala's answer about how to find the cause.

If one changes the base to "Console", i.e. using

base = "Console"

rather than

base = "Win32GUI"

a console will also pop up when the program starts and this error is printed

Intel MKL FATAL ERROR: Cannot load mkl_intel_thread.dll.

Which can help finding the cause of the problem pretty faster.

I thought this would be worth mentioning, since this trick can also be helpful to diagnose other problems. In the final release, one can revert back to Win32GUI to avoid the extra console. I should give the credits to this other stackoverflow post

Hashimoto
  • 306
  • 4
  • 8
2

I have followed @J.J. Hakala's answer, but I found that it's not necessary copy all mkl_*.dll and libiomp5md.dll files. For me it worked with libiomp5md.dll mkl_core.dll mkl_def.dll mkl_intel_thread.dll. This helps to reduce the final bundle size in ~500MB.

Also, you can include the files you want to copy in the include_files option. You also could only want to include them if sys.platform is win32.

I'm using Anaconda as well as @Matt Williams, so, changing a bit the OP's code:

import cx_Freeze
import matplotlib
import sys
import numpy
import tkinter
import os

PYTHON_INSTALL_DIR = os.path.dirname(os.path.dirname(os.__file__))

build_exe_options = {"includes":   ["matplotlib.backends.backend_tkagg","matplotlib.pyplot",
                             "tkinter.filedialog","numpy"],
                     "include_files":[(matplotlib.get_data_path(), "mpl-data")],
                     "excludes":[],
                    }

base = None

if sys.platform == "win32":
    base = "Win32GUI"
    DLLS_FOLDER = os.path.join(PYTHON_INSTALL_DIR, 'Library', 'bin')

    dependencies = ['libiomp5md.dll', 'mkl_core.dll', 'mkl_def.dll', 'mkl_intel_thread.dll']

    for dependency in dependencies:
        build_exe_options['include_files'].append(os.path.join(DLLS_FOLDER, dependency))

executables = [cx_Freeze.Executable("test.py", base=base)]

cx_Freeze.setup(
    name = "test it",
    options = {"build_exe": build_exe_options},
    version = "1.0",
    description = "I test it",
    executables = executables)
javrd
  • 712
  • 7
  • 19
0

Check if you have numpy+mkl package installed. Uninstalling numpy and installing numpy+mkl package solved my issue of getting error related to mkl_intel_thread.dll

arun babu
  • 1
  • 1