此內容主要說明如何實現 MATLAB 與 Python 協作的應用
- 目錄:
- 在 MATLAB 中呼叫 Python 函式 (Calling Python from MATLAB)
- 在 Python 環境下呼叫 MATLAB 函式 (Calling MATLAB from Python)
- 將 MATLAB 函式封裝成 Python package (Packaging MATLAB program to Python package)
對於以上三種情境會有一些對應的條件需求:
| 使用情境 | MATLAB Installed | Python Installed | MATLAB Runtime Installed | Compiler SDK Toolbox |
|---|---|---|---|---|
在 MATLAB 中呼叫 Python 函式 | ✔️ | ✔️ | ||
在 Python 環境下呼叫 MATLAB 函式 | ✔️ | ✔️ | ||
將 MATLAB 函式封裝成 Python package | ✔️ | ✔️ |
建議直接使用 Anaconda1 安裝並設定路徑,且方便之後根據不同狀況建立獨立環境安裝模組。
MATLAB 從 R2014b 開始支援 Python 2.7,建議至少使用 MATLAB R2020b 以上版本。
MATLAB Interface Engine 有支援對應 Python 版本的限制,詳細請見 MATLAB 官網支援版本列表
以下列出幾版:
| MATLAB 版本 | Python 2.7 | Python 3.6 | Python 3.7 | Python 3.8 | Python 3.9 | Python 3.10 | Python 3.11 |
|---|---|---|---|---|---|---|---|
R2023b | ✔️ | ✔️ | ✔️ | ||||
R2023a | ✔️ | ✔️ | ✔️ | ||||
R2022b | ✔️ | ✔️ | ✔️ | ✔️ | |||
R2022a | ✔️ | ✔️ | ✔️ | ✔️ | |||
R2021b | ✔️ | ✔️ | ✔️ | ✔️ | |||
R2021a | ✔️ | ✔️ | ✔️ | ||||
R2020b | ✔️ | ✔️ | ✔️ | ✔️ |
在 MATLAB 環境底下使用 Python 前可以透過 MATLAB 語法 pyenv2 來確認當前 MATLAB 有讀取到想要使用的 Python 版本。
除此之外 pyenv 具有以下參數可以讓使用者切換 Python 環境以及更改啟動模式Version:
Version 參數可以用來指定想要使用的 Python 版本
% Example: Set Python execution version for MATLAB interface engine% MATLAB Version: R2022b% 使用 Windows registry (Windows Only)
>> pyenv(Version="3.10")
% 使用完整路徑
>> pyenv(Version="/usr/bin/python")ExecutionMode:
ExecutionMode 參數設定是否要在和 MATLAB 同一個 process 底下執行 Python 程式碼 'InProcess' : 在 MATLAB process 中運行腳本。在對性能至關重要的使用情況下,請使用此模式。(Default)'OutOfProcess' : 啟動一個獨立的 process,用於安全執行Python腳本和模組並避免函式庫衝突。
- Python 模組需要使用與 MATLAB 相同的第三方庫的時
- 想要使用 Python 偵錯流程時
% Example: Set Python execution mode for MATLAB interface engine% MATLAB Version: R2022b% 設定執行模式
>> pyenv(ExecutionMode='OutOfProcess')
在 MATLAB 裡面可以直接使用 py 的前綴詞來使 MATLAB 調用 Python 裡面的既有函式,包含轉換變數型態等動作:
% Example: Create python list in MATLAB% MATLAB Version: R2022b
>> pyList=py.list([1,2,3])
pyList =Pythonlist with values:
[1.0, 2.0, 3.0]
Usestring, double or cell function to convert to a MATLAB array.
除此之外, py 的後綴也可以直接使用已安裝的 Python 模組, py 接上對應已安裝模組, MATLAB 即會自動 import:
% Example: Create scikit-learn regression model in MATLAB% MATLAB Version: R2022b
>> reg_Model=py.sklearn.linear_model.LinearRegression
reg_model =PythonLinearRegression with properties:n_jobs: [1×1 py.NoneType]
copy_X:1positive:0fit_intercept:1
LinearRegression()
使用 py 調用模組時,也可以使用 Tab 鍵來提示模組所含的物件與函式。
🚩 調用使用者自訂義函式 Calling User-defined Function
一般來說除了直接調用 python 函式庫裡面的函示之外,使用者可能會根據自身的需求去撰寫自訂義的函式或是函式庫。
在 MATLAB 中一樣可以透過 py 的前綴去調用這些自訂義的函式來使用。
若是要直接使用 py 前綴來調用使用者自訂義函式,需先確保該程式碼在 Python 的搜尋路徑底下:
在 MATLAB 底下將當下目錄加入 Python 搜尋路徑:
% Example: Add current directory to Python serach path% MATLAB Version: R2022b
>> if count(py.sys.path,'') ==0
insert(py.sys.path,int32(0),'');
end
Python User-defined Function:
# myModule.py# Sample script for calling user-defined function in MATLABimportnumpyasnpdefAddup_randiMat(A_max,B_max):
matA=np.random.randint(0,A_max,(2,2))
matB=np.random.randint(0,B_max,(2,2))
returnmatA+matB
在 MATLAB 中呼叫自訂義 Python 函式
% Example: Call Python user-defined function in matlab% MATLAB Version: R2022b
>> py.myModule.Addup_randiMat(10,5)
ans =Pythonndarray:47113Usedetails function to view the properties of the Python object.Useint64 function to convert to a MATLAB array.
🚩 載入使用者自訂義函式 Import User-defined Function as Module
除了前面提到的使用 py 前綴,MATLAB 也可以將 Python User-defined function script 以 module 的方式載入並儲存成物件變數
% Example: Load python module% MATLAB Version: R2022b
>> module=py.importlib.import_module('myModule')
module =Pythonmodule with properties:np: [1×1 py.module]
Addup_randiMat: [1×1 py.function]
<module'myModule'from'C:\\Users\\Tim\\Desktop\\myModule.py'>
如果 module 有所更動,在 MATLAB 中也可以透過 reload 來更新物件而不用再呼叫一次import
>> py.importlib.reload(module) 在 MATLAB 中可以使用字串的方式來表達 Python 程式碼,並透過 pyrun3 的函式來執行
% Example: Directly run python code % MATLAB Version: R2022b
>> pyCode= [
"Grocery = {'Apple':100, 'Orange':30}";
"Items = Grocery.keys()";
"Prices = Grocery.values()"];
>> [Items, Prices] = pyrun(pyCode, ["Items", "Prices"])
Items =Pythondict_keys with no properties.
dict_keys(['Apple', 'Orange'])
Prices =Pythondict_values with no properties.
dict_values([100, 30])
除了先前提到的 pyrun 使用字串表達 Python 程式碼之外,也可以執行既有的 Python 腳本並把想要的變數傳回 MATLAB workspace 中。
MATLAB 中的 pyrunfile4 讓使用者可以執行既有的程式碼腳本。
Python sample code:
# pyrunfile_demo.py# Demo script for MATLAB 'pyrunfile'importnumpyasnprandomMat=np.random.rand(100,100) # Create 100x100 of random matrix
MATLAB sample code
% Example: Run python script and get variable% MATLAB Version: R2022b
>> result= pyrunfile('pyrunfile_demo','randomMat')
result =Pythonndarray:Columns1 through 80.30910.97410.62380.02950.42980.45620.32160.65160.21240.77490.36960.23100.10580.02050.70970.56820.91840.30280.50640.55270.48720.52260.17890.3618
...
Usedetails function to view the properties of the Python object.Usedouble function to convert to a MATLAB array. 在 MATLAB 中調用 Python 的情境下最常遇到的問題就是 Python 端發生錯誤但卻沒辦法像 MATLAB 腳本一樣進入偵錯模式去查看變數變化。
但今天透過 VScode 的介面可以連結 MATLAB 程序來觸發 VScode 的中斷點。
- 在終端機輸入以下指令安裝
debugpy套件:
python -m pip install debugpy- 在想要偵錯的 Python 腳本中引入
debugpy套件並加入debugpy.debug_this_thread()程式碼,範例程式碼可以參考:
# Debug in User-defined Python Script with MATLABimportdebugpydebugpy.debug_this_thread() # Enable Debugging defAddup(x1,x2):
x1+=1x2*=10output=x1+x2returnoutput- 建立 VScode 偵錯調用腳本
launch.json
{
"version": "0.2.0",
"configurations": [
{ "name": "Attach to MATLAB",
"type": "python",
"request": "attach",
"processId": "${command:pickProcess}"
}
]
}NOTE: Ubuntu users may need to change the value of the ptrace variable using the command below.$ echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
確認 MATLAB 中所使用得 Python 環境以及程序ID,如果執行結果的
ExecutionMode顯示NotLoaded可以隨意執行一行 Python 程式碼
例如:py.list([1,2,3])
>> pyenv
ans =PythonEnvironmentwith properties:Version:"3.9"Executable:"C:\Users\Tim\anaconda3\envs\python39\python.exe"Library:"C:\Users\Tim\anaconda3\envs\python39\python39.dll"Home:"C:\Users\Tim\anaconda3\envs\python39"Status:LoadedExecutionMode:OutOfProcessProcessID:"19460"ProcessName:"MATLABPyHost"- 在 VScode 裡面點選 "Run and Debug" 並選擇 "Attach using Process ID" 連結到剛剛顯示的 MATLAB Process ID
在 MATLAB 中執行程式碼即可成功觸發 VScode 中斷點偵錯模式


MATLAB 在近幾年的版本中推出了許多將特定功能包裝起來的 APP,程式撰寫人員或是跨越不同領域的人能夠快速上手並節省開發時間。
對於習慣在 Python 環境開發的使用者或是想要在 Python 中開發但又希望沿用 MATLAB 特有功能的使用者可以參考本章節內容。
MATLAB 的目前釋出了與 Python 結合的 API 套件 matlabengine 一般可以在你的 MATLAB 安裝路徑底下找到: >> matlabroot\extern\engines\python
目前在 PyPI 上也有釋出該套件,所以使用者也可以直接透過 pip 指令安裝:
pip install matlabengine
在 Python 透過以下指令可以啟動 MATLAB 程序:
# Example: Start MATLAB API engine in Python# MATLAB Version: R2022b# Python Version: 3.9importmatlab.engineasengsession=eng.start_matlab('-desktop') # '-desktop' 參數會將 MATLAB 桌面顯示出來除此之外,如果有已經開啟的 MATLAB 程序也可以透過以下指令去連結:
# Example: Using current running MATLAB session# MATLAB Version: R2022b# Python Version: 3.9importmatlab.engineasengmatlab_ID=eng.find_matlab() # 選擇對應的 Process IDsession=eng.connect_matlab(matlab_ID[0])在 Python 中調用 MATLAB 和直接在 MATLAB 中使用的主要差異在於需要物件前綴和部分需要定義輸出數量。
以單純的產生亂數來看的話,在 Python 中調用 MATLAB 函式如下範例:
# Example: Call MATLAB function in Python# MATLAB Version: R2022b# Python Version: 3.9importmatlab.engineasengsess=eng.start_matlab()
matlab_rand=sess.rand(2)
print(type(matlab_rand))
print(matlab_rand)輸出:
<class'matlab.double'>
[[0.421761282626275,0.7922073295595544],[0.9157355251890671,0.959492426392903]]預設的輸出會是 MATLAB 物件的變數型態,可以透過 Numpy 套件轉換成 numpy.array
# Example: Convert MATLAB array to Numpy array# MATLAB Version: R2022b# Python Version: 3.9importnumpyasnpnp_array=np.array(matlab_randprint(type(np_array))
print(np_array)輸出:
<class'numpy.ndarray'>
[[0.421761282626275,0.7922073295595544]
[0.9157355251890671,0.959492426392903]]對於有多個輸出的函式需要特別去定義輸出的數量:
# Example: Call MATLAB function with multiple outputs# MATLAB Version: R2022b# Python Version: 3.9matlab_array=matlab.double([1,5,2,8,4,3]) # Convert list to MATLAB arraysorted_array, sort_idx=session.sort(matlab_array, nargout=2)
print(sorted_array, sort_idx)輸出:
[[1.0,2.0,3.0,4.0,5.0,8.0]] [[1.0,3.0,6.0,5.0,2.0,4.0]] 文章前面提到的兩種方式主要是在同時裝有 MATLAB 和 Python 的開發環境下進行協作,
但有另外一種使用情境是開發者想將既有的 MATLAB 演算法套件轉移到 Python 的框架下去使用。
要滿足這個需求除了重新用 Python 撰寫一次以外,比較省時且安全的辦法是將既有演算法轉換成 Python 的套件直接調用。
要將 MATLAB 程式碼編譯成 Python package 主要透過 MATLAB Compiler SDK® 來達成。(MATLAB Compiler Required)*
MATLAB Compiler SDK 除了 Python package 之外也支援多種其他程式語言的函式庫編譯5,如: .NET、C、C++、JAVA 等...
編譯的流程可以分為使用圖形化介面以及程式碼來達成,先以圖形化介面為例:
選取想要轉換的 MATLAB 程式碼,建議這裡的專案名稱可以使用後面要用來引入 Python 環境的 Package name
% addup.m% Sample funciton script for Python package compile functiony= addup(a,b) y =a+b;
編譯完成以後會產生三個資料夾,分別為:
- for_redistribution
- for_redistribution_files_only
- for_testing
在 for_redistribution_files_only 的資料夾中可以找到 `setup.py` ,透過以下的指令安裝在想要使用的 Python 環境中:python setup.py install
在 Python 環境中僅需先匯入 compiled 後的 package,並使用
initialize()去啟動MATLAB Runtime:# Example: Call compiled MATLAB function # MATLAB Version: R2022b# Python Version: 3.9importpyPackagemyLib=pyPackage.initialize() Result=myLib.addup(10,2) print(Result)
輸出:
12
Footnotes
Anaconda Official Website [https://www.anaconda.com/download] ↩
MATLAB
pyenvFunction Documentation [https://www.mathworks.com/help/matlab/ref/pyenv.html] ↩MATLAB
pyrunFunction Documentation [https://www.mathworks.com/help/matlab/ref/pyrun.html] ↩MATLAB
pyrunfileFunction Documentation [https://www.mathworks.com/help/matlab/ref/pyrunfile.html] ↩MATLAB Compiler SDK [https://www.mathworks.com/products/matlab-compiler-sdk.html] ↩




