Introduction: How to Use Plotly MATLAB/Octave API

Have you ever wondered about the electromagnetic fields (EMF) around a high voltage power line? I recently published a post about it on my blog and I thought this would be a perfect opportunity to try using plot.ly.

On this instructable, I'll show you how I used the MATLAB API for plotly to create heatmaps, representing the electromagnetic fields. 

I'll also show how I used the same API on Octave (the open source alternative to MATLAB).

Step 1: The Problem

First let's get into the context:
(you can skip this step if you're only interested in plotly)

The situation I'm analyzing is a transmission line, 3-phased, 50 Hz alternating current power line considering a voltage of 400kV and a power of 1200MVA. Each phase is composed of 2 conductors ("bundled" 2 ways). There are also 2 overhead earth wires or shield wires on the top of the tower. All the important distances are represented on the previous image (in meters).

The section being studied is an area perpendicular to the length of the conductors, considering 40 m for each side from the center of the tower (on the X axis) and a height of 50 m from the ground (on the Y axis).

The electromagnetic field, as the name says, is made of 2 components, the electric field and the magnetic field. This work will analyze them separately in different time instants.

Step 2: Physics and Mathematics

Now comes the boring part.

In order to calculate the electric and magnetic fields, many steps are necessary, mathematical equations, laws of physics, etc.

Since this instructable is about using plot.ly I'll skip this part, and focus only on the API for sending data from MATLAB or Octave to the plotly website.

But, if you are still interested in learning the calculations, you can always check my blog where I explain that part in detail.

So, from this step on, let's just consider I have my MATLAB/Octave algorithm that calculates the EMF and outputs a matrix with that data.

Step 3: Starting With Plotly

Now let's get started with plotly.

Plotly is an online analytics and data visualization tool, that provides online graphing, among other tools, for individual use or collaboration, as well as scientific graphing libraries for Python, MATLAB, Arduino, etc.

First let's create a plotly account, it's easy, it's quick and the best of all, it's free! Go to their website and sign up for an account.

When you've created and activated your account you're ready to go!

If you are new with plotly, maybe you should try and create first a simple online graph, by uploading data from a table or an excel file for example, to learn about how it works and all the possible customizations.

Then let's move to the API:

To be able to start sending data to your plotly account from an API, first you need your API Key. Go to your profile settings and click on "generate new key", in the API Key field. Now you should have your new API Key!

That key is used by plotly to identify you when you're uploading data to the website, and it serves as the authentication process to access your account. We will see how, on the next steps.

Now it's time to install the plotly API.
Go to the plotly MATLAB API page and download the zip archive.

Then unzip it and save it on the location you want.
In my case, I saved it on the same directory as MATLAB:
C:/Program Files/MATLAB

Step 4: Sending Data With MATLAB

Directories:

So the first thing you need to do is to add the directory where you saved the API data files to the MATLAB directory.

You can do this by adding these lines to your code:

>>> api_path = 'C:/Program Files/MATLAB/plotlyAPI/plotly';
>>> addpath(genpath(api_path))

Don't forget to change the directory above, in case you used a different location than me.


Authentication:

Now you must sign into your plotly account through your code. This is done using this line:

>>> signin('joaoduarte', 'my_api_key')

You must change the strings accordingly to your settings. The first string is your plotly username, in my case is 'joaoduarte' and the second string is your API Key, that you generated in the previous step, in your plotly profile settings.

Personally I like to put these lines with settings on the beginning of my code, since they are part of the general configurations, but you can use them anywhere you want, as long as they come before you start calling the plotly functions.


Data:

When you're sending data from the MATLAB API, you're basically sending JSON objects to the plotly website. These objects follow a very specific and organized structure, divided in parts, like data and layout.

The data part is basically an array with all the data trace info, like X, Y and Z points for example, as well as the settings for the graph itself, like the graph type and style.

To send data info from MATLAB to plotly we can use an API function called plotly(). In my case, I want to send the x data, where X is an array, basically with the length of the X axis (40 m for each side, being 0 in the center), the y data, where Y is also an array but with the height of the area (from the ground to 50 m high) and the z data, which in my case can be either the matrix 'K' or 'C' (for electric and magnetic values, respectively). Besides, I will also send information about the graph type I want, in this case it's a 'heatmap' and the color scaling I like, which is defined in the 'scl' field. So these is what I need to write:

>>> dataM = struct('x', X, 'y', Y, 'z', C, 'type', 'heatmap',...
        'scl',{{{0,'rgb(0,0,131)'},{0.125,'rgb(0,60,170)'},...
        {0.375,'rgb(5,255,255)'},{0.625,'rgb(255,255,0)'},...
        {0.875,'rgb(250,0,0)'},{1,'rgb(128,0,0)'}}},...
        'showscale', false)

>>> plotly({dataM}, struct('filename', nameM, 'fileopt', 'overwrite'))

The plotly function also allows you to decide the name of the graph file you're creating on your plotly gallery, and if you're creating a new file or overwriting an existing one. These are done with the 'filename' and 'fileopt' fields. In my case, the variable 'nameM' is a string with the name I want the graph to have.

The function plotly() returns a response from plotly website that should look something like this:

     url: 'https://plot.ly/~joaoduarte/8'
     message: [1x0 char]
     warning: [1x0 char]
     filename: 'Electric Field for t = 6.667 ms'
     error: [1x0 char]

After you received this response, your graph is ready on your plotly gallery!

In my case, I'm sending a LOT of data points with this API, so to give you an idea, it takes my computer almost a minute to calculate them all and to send them to plotly. So this response might take a little bit to be received.


Layout:

Now the layout part is basically an object with additional global chart layout settings, like the graph title, the axis labels, special annotations, among other things. To send layout info from the plotly MATLAB API, you can use the function plotlylayout().

In my case I will use this functionality to give the graph a title, to label the X and Y axis, and also to put the filename as an annotation beneath the graph. I will need to write these lines:

>>> layoutM = struct('title', 'Magnetic Field Spacial Distribution',...
        'xaxis', struct('title', 'X Axis [m]'),...
        'yaxis', struct('title', 'Y Axis [m]'),...
        'annotations',{{struct('text', nameM,...
        'xref', 'paper', 'yref', 'paper',...
        'x', 0, 'y', -0.15, 'align', 'left',...
        'showarrow', false)}})

>>> plotlylayout(layoutM)

The plotlylayout() function also returns a response like this:

     url: 'https://plot.ly/~joaoduarte/8'
     message: [1x0 char]
     warning: [1x0 char]
     filename: 'Electric Field for t = 6.667 ms'
     error: [1x0 char]

Like before, this means your new graph is ready in your gallery!


Additional Info:

The specific structure of the JSON object might be a little confusing at first, and you need to respect it for the API to work properly. In case of doubts, you should check out the API documentation for more information about the specific parameters of each function, rules, and other functionalities that I haven't used in this example. You can find it here, not only for MATLAB but also for Python, Arduino, Raspberry PI, among others. For general information about plotly JSON Objects, check the REST API documentation.

Another good thing you can do, is to check the JSON file of the graph, on your plotly web editor. There you can see what you actually sent or how you should send the data.

Step 5: Sending Data With Octave

Adapting the API:

The steps for using the plotly API on Octave are pretty much the same as in MATLAB, however there is a small thing you need to do first, which is to change the API file, named 'makecall.m'.

You can find this file on the zip archive you downloaded, in the directory: /plotly/plotly_aux.

The only thing you need to do here is changing the word 'Post' to 'post' on line 10. Then you're ready to go!

From here on, it's all basically the same. For my case, I just had to change a few other things on the data and layout part, but I'll explain on those sections.

On this step, I'll focus more on the alterations I've done. Check the "Sending Data with MATLAB" step, for detailed info about each function.


Directories:

Here is exactly the same as MATLAB, changing only the directory:

>>> api_path = '/home/Joao/PlotlyAPI/plotly';
>>> addpath(genpath(api_path))


Authentication:

The sign in process is also the same:

>>> signin('joaoduarte', 'my_api_key')


Data:

So here is where I started having troubles. The data from my 'scl' field was formed by a cell of arrays with numbers and strings. The numbers had decimal points, that for some reason, were not being sent. Octave calculated them properly, but they were not being sent correctly.

I thought it might be because of the Ubuntu system language and regional format being in Portuguese, but I changed it to English, and nothing happened. I eventually fixed it by turning those numbers into strings, however, there might be a better solution.

I had the same problem with my X and Y arrays, when their increments were inferior to one, also because of the decimal point. What I've done here was to create new vectors, with the same size, but with an increment of one, changing their limits.

This works, but the axis limits on plotly will come out wrong. So I needed to fix them, by sending my customized scale within the plotly() function.

So here is the resulting code:

>>> XX=-400:1:400;  %before was from -40 to 40 with increments of 0.1
>>> YY=0:1:500;        %before was from 0 to 50 with increments of 0.1

>>> dataE = struct('x', XX, 'y', YY, 'z', K, 'type', 'heatmap',...
        'scl',{{{'0','rgb(0,0,131)'},{'0.125','rgb(0,60,170)'},...
        {'0.375','rgb(5,255,255)'},{'0.625','rgb(255,255,0)'},...
        {'0.875','rgb(250,0,0)'},{'1','rgb(128,0,0)'}}},...
        'showscale', false,...
        'xtype', 'scaled', 'x0', '-40', 'dx', '0.1',...
        'ytype', 'scaled', 'y0', '0', 'dy', '0.1')

>>> plotly({dataE}, struct('filename', nameE, 'fileopt', 'overwrite'))

As you can see, inside the 'scl' field, the numbers are now between single quotation marks, turning them into strings. The XX and YY variables, are my new arrays, with an increment of one.

The new functionalities used here are the 'xtype' and 'ytype' field names. This allow you to use the scale you want on the X and Y axis of your graph. The 'x0' and 'y0' are the first values, and the 'dx' and 'dy' are the increments. For example, on the Y axis, I want it to be from 0 to 50, with increments of 0.1, but I'm sending data from 0 to 500 with increments of 1, so I'll use these options to change it. I'll put 'y0'=0 and 'dy'=0.1, this will output the Y axis from 0 to 50.

So this problem came as a good thing, because it made me learn more functionalities about the plotly API.

Finally, this should output a response like the one observed on the previous step.


Layout:

For my case, in the layout part, there was only one little thing to change, because of the same decimal point problem. Which was on the 'annotations' structure, more specifically on the 'y' field, because it has the value -0.15. The fix was the same as before, turning it into a string with single quotation marks. Again, there might be a better solution for this, but this one worked fine for me.

So the plotlylayout() function comes as:

>>> layoutE = struct('title', 'Electric Field Spacial Distribution [Octave]',...
        'xaxis', struct('title', 'X Axis [m]'),...
        'yaxis', struct('title', 'Y Axis [m]'),...
        'annotations',{{struct('text', nameE,...
        'xref', 'paper', 'yref', 'paper',...
        'x', 0, 'y', '-0.15', 'align', 'left',...
        'showarrow', false)}})

>>> plotlylayout(layoutE)

All the rest was kept as it was. This function should also return a response like on the previous step.


Additional Info:

Like before, don't forget to check the API documentation page for detailed informations about the JSON objects.

Also, be sure to try the JSON viewer on the plotly web app.

Step 6: Final Results

Finally is time for the results!

In the images above you can check the graphs obtained in plotly, MATLAB and also in Octave. As you can see, they are pretty much similar.

You can check them for yourself through these links:

Electric field for t=1.667ms: https://plot.ly/~joaoduarte/6/
Magnetic field for t=1.667ms: https://plot.ly/~joaoduarte/7/

Electric field for t=5ms: https://plot.ly/~joaoduarte/12/
Magnetic field for t=5ms: https://plot.ly/~joaoduarte/13/

Electric field for t=6.667ms: https://plot.ly/~joaoduarte/8/
Magnetic field for t=6.667ms: https://plot.ly/~joaoduarte/9/

Electric field for t=20ms: https://plot.ly/~joaoduarte/10/
Magnetic field for t=20ms: https://plot.ly/~joaoduarte/11/

Electric field for t=1.667ms and V2=0: https://plot.ly/~joaoduarte/14/
Magnetic field for t=1.667ms and V2=0: https://plot.ly/~joaoduarte/15/

And the ones from Octave:
Electric field for t=6.667ms: https://plot.ly/~joaoduarte/16/
Magnetic field for t=6.667ms: https://plot.ly/~joaoduarte/17/

And that's it. I hope this instructable helps you with the plotly API for MATLAB or Octave.

If you're curious about the calculations for the electromagnetic fields, check out my blog: The Fragmentation Paradox
You can also find the full algorithm there.

Data Visualization Contest

Participated in the
Data Visualization Contest