How to call a MATLAB Script in Python 3.9?

Viewed 1931

I have a MATLAB .m file and want a Python.py file to be able to run/call that .m file, however it seems calling MATLAB files using 'import matlab.engine' isn't supported in Python 3.9 (what Im running) and was cut after 3.7

My questions is what is the proper convention to call a MATLAB script in Python 3.9?

EDIT: When I say 'call a MATLAB script', I mean run the script on it's own. Using the .py file to open the MATLAB window kind of defeats the purpose of this project.

2 Answers

This answer is for Python 3.6 but it should be applicable to 3.9 as well. On a Linux machine (and MacOS, possibly with slight modifications), you can execute a system command which opens MATLAB, runs your script, and then closes MATLAB,

import subprocess

run_matlab = 'matlab -nodisplay -nojvm -nosplash -nodesktop -r "try, test_script, catch e, disp(getReport(e)), exit(1), end, exit(0);"'

subprocess.run(run_matlab, shell=True, check=True)

The purpose of the try-catch block is to properly exit from MATLAB after executing the script test_script in case when the script raises an exception - throws an error. One could instead just exit (exit or quit in MATLAB returns proper exit code by default on those two OS), but with a try-catch block there are more opportunities to fix, notify, or save things when an exception occurs. This may be generally useful when running outside an interactive session.

The rest of the command opens MATLAB with no display of any kind, runs the script test_script, and exits MATLAB - exit(1) signifying an exception was raised, and exit(0) meaning that all went well.

Without the try-catch the command is much simpler,

run_matlab = 'matlab -nodisplay -nojvm -nosplash -nodesktop -r "test_script; exit;"'

On the Python side, I use subprocess.run() (or .call()) since it is newer, and recommended. The option shell means that the command will be executed through the shell. check means that if the run_matlab process (command) throws an error, the Python script will also throw one. The default is False and along with the try-catch block may be used to swiftly ignore crashing code.


As @CrisLuengo said in his comment, starting with MATLAB 2019a (MATLAB 2018b indeed does not have it) there is no need for the elaborated command above. All you need is

run_matlab = 'matlab -batch test_script.m'

Looking at the documentation, -batch invokes all the necessary options, and more.

This is more of a hack fix, but you can edit the Python package for the matlab engine on your system and bypass the version checker. Since Python is backwards compatible it shouldn't be a problem, depending on your use case.

Open the following file on your system (or the equivalent file under matlab engine):

vim /usr/lib/python3.9/site-packages/matlab/engine/__init__.py

In that file, change line 31 to include Python 3.9:

_supported_versions = ['2_7', '3_6', '3_7', '3_8', '3_9']

Finally, in line 37, change the version number to a valid version.

    _PYTHONVERSION = '3_7' # or another new, supported version

After this, you should be able to run matlab's engine as if Python 3.9 were supported.

Related