Py_Addpath
Sean‘s pick this week is py_addpath directory matlab_too by Eric Fields.
Using Python with MATLAB
Do you have some Python code from a colleague or a snippet from GitHub that you’d like to use in MATLAB and not have to rewrite it? You can do that through the Python Interface for MATLAB.
A simple “hello world” example is as follows:
s = py.str("hello world") % Convert MATLAB string to py.str whos s sc = string(capitalize(s)) % Convert capitalized str back to MATLAB string
s = Python str with no properties. hello world Name Size Bytes Class Attributes s 1x11 8 py.str sc = "Hello world"
Now what if you want to call your custom Python code? Well the Python interpreter current working directory is the current MATLAB directory:
cwd = py.os.getcwd
cwd = Python str with no properties. C:\Documents\MATLAB\potw\PyAddPath
So if your code lives here, you’re all set. However, you may (probably!) have your Python code somewhere else. So this is where this week’s submission comes in. You can use py_addpath to add another directory to the Python interpreter’s path. Optionally, it can also add the directory to the MATLAB path.
Personally, I’m no longer modifying the MATLAB path myself and using (and recommending!) Projects for anything where path or other setup needs to be configured. Because Projects afford us a “Run at Startup” option, I can have it run MATLAB code that takes care of the Python path as well using Eric’s py_addpath.
Let’s take a look at an example. NOTE: Everything we’re doing with Python here could also be done with MATLAB’s webread but we’ll pretend we’re obligated to use this Python function.
Here’s the Python function:
""" dataLib.py imports 1-minute bars from GDAX built with Python 3.5 on 4/3/2018 Example: getPriceData('ETH', '2018-03-16T17:41:26Z', '2018-03-16T18:14:46Z') To call from Python: >>import dataLib >>dataLib.getPriceData('ETH', '2018-03-16T17:41:26Z', '2018-03-16T18:14:46Z') """ def getPriceData(product, start, stop): import urllib.request import json # all cryptocurrency products returned in USD product = product + '-USD' # granularity is in seconds, so we are getting 1-minute bars granularity = '60' # returns back: [time, low, high, open, close, volume] url = 'https://api.pro.coinbase.com/products/' + product + '/candles?start=' + start + '&end=' + stop + '&granularity=' + granularity # execute call to the website urlRequest = urllib.request.Request(url, data=None, headers={'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.47 Safari/537.36'}) response = urllib.request.urlopen(urlRequest) html = response.read() # python 3.x requires decoding from bytes to string jsonData = json.loads(html.decode()) return jsonData ########################################################################################### def parseJson(json_data): from array import array # return back time and close data dates = [row[0] for row in json_data] data = [row[4] for row in json_data] # convert to 1D array dateArray = array('d') dataArray = array('d') dateArray.fromlist(dates) dataArray.fromlist(data) # wrap both time series in a dictionary closeTimeSeries = {'Date': dateArray, 'Close': dataArray} return closeTimeSeries
And here’s the function I would add to the project startup to add the Python folder at project startup.
function addPythonDataLib() prj = currentProject; py_addpath(fullfile(prj.RootFolder, 'Python')); end
Now after opening the project, we can use the dataLib.py functionality.
% Query for Ethereum prices startDate = '2018-03-16T12:00:00Z'; stopDate = '2018-03-16T17:00:00Z'; jsonData = py.dataLib.getPriceData('ETH', startDate, stopDate); data = py.dataLib.parseJson(jsonData); % Convert to MATLAB Data Types data = struct(data); data.Date = double(data.Date)'; data.Date = datetime(data.Date, 'ConvertFrom', 'posixtime', 'TimeZone', 'America/New_York'); data.Close = double(data.Close)'; data = table2timetable(struct2table(data)); disp(head(data)) stackedplot(data);
Date Close ____________________ ______ 16-Mar-2018 13:00:00 621.1 16-Mar-2018 12:59:00 621.1 16-Mar-2018 12:58:00 621.1 16-Mar-2018 12:57:00 621.09 16-Mar-2018 12:56:00 621.09 16-Mar-2018 12:55:00 621.09 16-Mar-2018 12:54:00 621.06 16-Mar-2018 12:53:00 621.87
One suggestion for Eric, is that the function could use convertStringsToChars to allow for MATLAB string inputs to be passed in as well without needing to change any algorithmic parts. I.e.
directory = convertStringsToChars(directory);
Comments
Give it a try and let us know what you think here or leave a comment for Eric.
Published with MATLAB® R2019b
- Category:
- Picks
Comments
To leave a comment, please click here to sign in to your MathWorks Account or create a new one.