I wanted to use the Python library from MATLAB

Introduction

About this article

MATLAB and Python each have their advantages. MATLAB is strong in matrix operations, and its strengths include Japanese documents and the existence of Simlinks. On the other hand, Python is free to use, and rich machine learning libraries such as scikit-learn are attractive. Therefore, you may want to use these properly.

For such cases, there is Ability to call Python directly from MATLAB. (Conversely, Call MATLAB function from Python is also possible, but I will not touch it this time.)

However, even if I look it up, the official document is not very practical [^ example]. Therefore, this time, I will organize and summarize ** information that seems to be useful in practical use **.

What I wanted to do

In the past, there were times when I wanted to process the machine learning part in Python and use MATLAB to prepare training data and evaluate the model. You could write and execute the code in each language and exchange the results in a dat file or mat file, but it was a little troublesome. So, when I learned about this function, I thought, "I can make it easier!" (Actually, the conclusion I looked up was "** Python calls from MATLAB are not desirable **")

[^ example]: There is only an example of textwrap.wrap, and I have no idea how to actually use numpy etc ... (I think I wanted to explain it only with the standard library)

Preparing to use python

Before using it in MATLAB, you need to install the Python interpreter and register its path. However, since python has Official version and Anaconda version, the procedure changes a little. I will.

To use the official version of Python.org, install according to Explanation here. only.

On the other hand, if you do not pass the path in the Anaconda environment or the official version, you need to set the path individually on MATLAB. First, find out the path of the interpreter you want to use. Then, set the path checked by pyversion function. For example, to use Anaconda's hogehoge environment, write as follows.

executable = [getenv('userprofile'),...
     '\AppData\Local\Continuum\anaconda3\envs\hogehoge\python.exe'];
pyversion(executable);
clearvars executable;

Run pyversion with no arguments to see if it's set up properly. If the version is displayed, it should be okay.

Process using Python

Call a python function

Next, let's call a Python function. To call a function named command in Python from MATLAB, just use py.command. For example, if you want to execute the print function of python, do as follows.

py.print("Hello world!");

However, it should be noted that MATLAB and Python have different built-in data types and grammars. For example, even if it is possible in Python, the following notation is not allowed.

py.print("{0} {1}".format("Hello", "world!"));

%  py.print("{0} {1}".format("Hello", "world!"));
%                    ↑
%error:Unexpected MATLAB operator.

For proper execution, [explicitly convert MATLAB String type to Python string type](https://jp.mathworks.com/help/matlab/matlab_external/handling-data-returned-from- python.html) You need to do it.

py.print(py.str("{0} {1}").format("Hello", "world!"));

How to import

Next is about How to import Python packages. The above page describes the syntax equivalent to from x import y in python. However, in practice, syntax like ʻimport numpy as np` is often used. This can be written as follows from Implementation of import statement on the python side.

%Code equivalent to import numpy as np in Python
np = py.importlib.import_module('numpy');

How to pass a matrix (MATLAB to nd array)

Data type conversion occurs when exchanging data between MATLAB and Python. The automatic conversions are MATLAB to Python, [Python to MATLAB](https: // It is organized in jp.mathworks.com/help/matlab/matlab_external/handling-data-returned-from-python.html#buialof-53). Here, when passing a 1-by-N vector to Python, it is automatically converted to the built-in array type. However, the M-by-N matrix does not seem to be converted automatically.

matrix = np.array(rand(2));

%error: py.builtin_function_or_method/subsref
% MATLAB 'double'Conversion to Python is 1-Only supported for N vectors.

Therefore, using the fact that Matlab's cell array is automatically converted to Python tuples, it seems that it can be converted to ndarray form by doing the following.

mat_org = rand(2);
for i = 1:size(mat_org, 1)
    mat_cell{i} = mat_org(i, :);
end
matrix = np.array(mat_cell);

disp(mat_org);       %Original matrix(MATLAB)
py.print(matrix);    %Matrix after conversion(ndarray)

It is troublesome to write a for statement every time, so it is better to use it as a function.

mat2ndarray.m


function ndarray = mat2ndarray(mat)
% ndarray = mat2ndarray(mat)Convert matrix to python ndarray format and return

validateattributes(mat, {'numeric'}, {'2d'})
n_rows = size(mat, 1);
mat_cell = cell([1, n_rows]);

for r = 1:n_rows
    mat_cell{r} = mat(r, :);
end
ndarray = py.numpy.array(mat_cell);
end

How to execute a function with parameters

In python, Specify the parameter name and pass it to the function may occur. In this case, the problem is that MATLAB and Python have different grammars. As a solution, use MATLAB's pyargs function.

For example, to find the average for each column of a matrix with numpy, do as follows.

mat = mat2ndarray(rand(2));
%Np in python.average(a=mat, axix=0)Equivalent to
ave = np.average(pyargs('a', mat, 'axis', py.int(0)));

It should be noted here that MATLAB basically treats numbers as double type.

Receive results from Python

How to receive a matrix (ndarray to MATLAB)

When the processing in Python is finished, you will return to the basic type of MATLAB and plot it. In that case, it is necessary to convert to a MATLAB matrix, but it cannot be simply converted as shown below.

n_mat = np.average(pyargs('a', mat2ndarray(rand(2)), 'axis', py.int(0)));  %Some processing result
double(n_mat);    %I want to convert to a matlab matrix
%error: double
% py.numpy.Unable to convert from ndarray to double.

Therefore, it needs to be converted as well as [How to pass a matrix](# How to pass a matrix (MATLAB to ndarray)). Therefore, once converted to a vector of type ʻarray.array, use the information of ndarray.shape` to [reshape function](https://jp.mathworks.com/help/matlab/ref/reshape. Shape it with html). Specifically, it can be converted with the following function [^ refdiscussion].

function mat = ndarray2mat(ndarray)
% mat = narray2mat(mat)Converts python narray format matrix to MATLAB format matrix and returns

validateattributes(ndarray, {'py.numpy.ndarray'}, {'scalar'});
np = py.importlib.import_module('numpy');

shape = cell(ndarray.shape);            %Read the shape
shape = cellfun(@(x) int64(x), shape);  % py.Convert int to int64

if shape == 1
    %For scalars, prevent errors
    shape = [1, 1];
end

%Read data as vector
data = py.array.array(ndarray.dtype.char, np.nditer(ndarray));
data = double(data);                    % py.array.Convert array to double
mat = reshape(data, shape);             %Arrange the shape in a matrix
end

[^ refdiscussion]: I referred to this discussion.

I want to display data with matplotlib

Let's display the result with matplotlib without relying on the MATLAB plotting tool [^ matplotlib]. However, in my environment (Anaconda), a Qt-related error occurred and I could not plot.

So, I added environment variables by referring to this article, and I was able to plot well. Below is the code to add the Qt path for the hogehoge environment.

QtPath = [getenv('userprofile'),...
    '\AppData\Local\Continuum\anaconda3\envs\hogehoge\Library\plugins'];
setenv('QT_PLUGIN_PATH', [getenv('QT_PLUGIN_PATH'), QtPath]);
clearvars QtPath;

If I put this code in startup.m, I could plot it properly.

[^ matplotlib]: It is strange to use matplotlib, which provides MATLAB-like graph drawing, on MATLAB ...
However, I feel that matplotlib is better for the default color scheme.

I want to use sklearn and seaborn

If you use Python, you want to use scikit-learn or seaborn. However, it seems that these cannot be imported for some reason.

%I can't even see the help ...
py.help('seaborn')
% problem in seaborn - ImportError: DLL load failed:The specified procedure cannot be found.

If anyone knows the cause or solution, please let me know ...

in conclusion

The above is the method of using Python from MATLAB in the range I investigated. In conclusion, I thought it would be overwhelmingly easier to execute ** individually and hand over the files **. I think it's many times easier to write a process to pass a csv file using a library than to learn how to call Python from MATLAB.

<!-Also, if you set the process to transfer files, transfer to other languages will be smooth. ->

Also, in my environment, it is fatal that ** scikit-learn cannot be used **. If it's just the numpy and scipy features, I think the MATLAB built-in functions are more powerful.

In addition, spyder and pycharm provide support such as powerful code completion, but MATLAB provides poor support.

Considering the above, the current "Python call from MATLAB" is not a very good method. However, there are some parts that have not been fully investigated, so if you are familiar with it, I would appreciate it if you could supplement it with comments.

Alternative

As an alternative, it is better to prepare MATLAB script and Python script respectively, and exchange data by file or standard input / output. For example, if you have a main MATLAB script (main.m) and a Python script (hogehoge.py) that performs processing, the processing will be as follows.

  1. main.m prepares the data and writes it to the input file
  2. Run a Python script from main.m like ! Python hogehoge.py
  3. hogehoge.py processes and saves to output file
  4. read the processed data from the output file by main.m

References

  1. Introduction to python in MATLAB (MATLAB official document)
  2. Problems that are said to be undefined when using py (Qiita article)
  3. pyversion function (MATLAB official documentation)
  4. Convert from numpy array to double (https://jp.mathworks.com/matlabcentral/answers/157347-convert-python-numpy-array-to-double) (MATLAB Answers)
  5. Python function arguments (MATLAB official documentation)

Recommended Posts

I wanted to use the Python library from MATLAB
I want to use jar from python
How to use the C library in Python
I want to use MATLAB feval with python
I want to use ceres solver from python
[Python] How to use the graph creation library Altair
I want to use the R dataset in python
I wanted to visualize 3D particle simulation with the Python visualization library Matplotlib.
How to use Requests (Python Library)
[Python] How to import the library
Use the Flickr API from Python
I tried using the Python library from Ruby with PyCall
I wanted to solve the Panasonic Programming Contest 2020 with Python
[python] How to use the library Matplotlib for drawing graphs
[Python] I want to use the -h option with argparse
I didn't know how to use the [python] for statement
I tried changing the python script from 2.7.11 to 3.6.0 on windows10
Pass OpenCV data from the original C ++ library to Python
I created a Python library to call the LINE WORKS API
I wanted to solve ABC160 with Python
I wanted to solve ABC159 in Python
I wanted to solve the ABC164 A ~ D problem with Python
I wanted to solve ABC172 with Python
About the error I encountered when trying to use Adafruit_DHT from Python on a Raspberry Pi
I was able to print the thermal printer "PAPERANG" from Python (Windows10, Python3.6)
Tips for Python beginners to use the Scikit-image example for themselves 9 Use from C
Use Python from Java with Jython. I was also addicted to it.
I wanted to solve NOMURA Contest 2020 with Python
Study from Python Hour7: How to use classes
How to use Python Image Library in python3 series
I want to email from Gmail using Python.
[Python] I want to manage 7DaysToDie from Discord! 1/3
Specify the Python executable to use with virtualenv
I wanted to play with the Bezier curve
I wanted to install Python 3.4.3 with Homebrew + pyenv
[Bash] Use here-documents to get python power from bash
How to use the graph drawing library Bokeh
The easiest way to use OpenCV with python
I want to use Temporary Directory with Python2
[Algorithm x Python] How to use the list
Use the Python framework "cocotb" to test Verilog.
Call Python library for text normalization from MATLAB
What I did when updating from Python 2.6 to 2.7
[Python] I want to manage 7DaysToDie from Discord! 2/3
I want to make C ++ code from Python code!
[Python] I will upload the FTP to the FTP server.
Use the LibreOffice app in Python (3) Add library
Use the nghttp2 Python module from Homebrew from pyenv's Python
I want to use the activation function Mish
I want to display the progress in Python!
Use Tor to connect from urllib2 [Python] [Mac]
Python: Use zipfile to unzip from standard input
Use thingsspeak from python
Use fluentd from python
Changes from Python 3.0 to Python 3.5
Changes from Python 2 to Python 3.0
Use MySQL from Python
Use MySQL from Python
Use BigQuery from python.
Use mecab-ipadic-neologd from python
python I don't know how to get the printer name that I usually use.