MATLAB Primer - Module 7

Now that you've had experience using the MATLAB editor interface and have been exposed to a growing sense of matrices, we can continue with some final thoughts in this last module. Let's consider a full simulation with some review and then instruction on creating a video across timesteps.

We will start off by initializing the same 3-D matrix we used last module as a new script in the MATLAB editor interface. Create a new script and call it matrix5.m. Then start the script off by copying:
T = [14.9 15.0 15.2 15.4; 14.2 14.3 14.5 14.7; 13.4 13.69 13.9 14.2]
T(:,:,2) = [15.001 15.14 15.298 15.4; 14.38 14.407 14.65 14.7; 13.516 13.8031 14.0110 14.2]
T(:,:,3) = [15.121 15.3 15.39 15.91; 14.449 14.129 14.789 14.95; 13.638 13.51 14.209 14.449]
T(:,:,4) = [15.32 15.297 15.11 15.51; 14.208 14.178 14.119 15.57; 13.745 14.259 14.297 14.149]
T(:,:,5) = [15.28 15.22 15.582 15.783; 14.656 14.216 14.37 15.59; 13.571 14.357 14.374 14.256]
T(:,:,6) = [15.395 15.401 15.803 15.805; 14.793 14.244 15.46 15.20; 13.685 14.443 14.444 14.793]
and pasting it into the Script Editor. Save the script, and use the Run button to run it. You should see no error messages.

We now have our familiar 3-D matrix (assigned with a label we chose of T) in MATLAB's managed computing memory.

Remember that we are considering this data to be the end state after running a simple temperature prediction model.

We'll go back to module five to borrow code that loops through the data. Add the following ten lines after the declaration of matrix T:
time = [0,1,2,3,4,5]

for time=1:6
    figure
    pcolor(T(:,:,time))
    
    xlabel('Longitude')
    ylabel('Latitude')
    title('Temperature change for all locations','FontSize', 18)   
    shading interp
    colormap jet
end
Running the code so far (by clicking on the Run button), we see the six timestep figures are more varied than when we used a simple linear formula to update the temperature each time step.

And yet, since we want to create a video, we want the data range for the axes and on the figures to be identical each timestep.

We can use the axis function to make explicit bounds by typing:
axis([1 4 1 3])
after the colormap jet line of code.

This guarantees the x axis will range from 1 to 4 and the y axis will range from 1 to 3.

And we can use the caxis function to set the colormap range to be identical in each frame (which then can highlight the overall increasing temperature trend over time).

Type:
caxis([10 50])
after the axis([1 4 1 3]) line of code

Running the code so far (by clicking on the Run button), we see the six timestep figures become increasingly redder over time.

Animation has become more and more popular as an approach to seeing change in data conveniently. We can use MATLAB code functions to create a movie from our timestep figures.

We will use the VideoWriter function to create a movie.

There are many options we can use with the VideoWriter function but let's just look at the frame rate options as an example.

Let's set up our VideoWriter with three lines of code we type after the time = [0,1,2,3,4,5] line of code:
v = VideoWriter('temperature.avi')
v.FrameRate = 2
open(v)
We use a variable v to reference our VideoWriter and then change the FrameRate property to 2 frames a second (500 milliseconds per frame) through the v reference (also called a handle).

We have to set all our properties before we open the writer so we can write video frames to it.

We can now write our figures as frames to the VideoWriter via two lines of code we type right before the end statement within our timestep loop:
frame = getframe(gcf)
writeVideo(v,frame)
The gcf variable is used internally by MATLAB. We don't need to initialize it ourselves.

Now that we are writing our figures to video, we don't need for MATLAB to create windows for them.

As a result, we can delete the figure statement that is at the top of our loop code if we don't want to see them.

The VideoWriter is writing to MATLAB memory to create a video of the AVI format.

When we are done creating all the frames in the movie, we let MATLAB know it can flush memory to the hard drive within the file we identified in the VideoWriter constructor function (temperature.avi) by typing:
close(v)
as the last line in our script.

The temperature.avi file is created (or rewritten if we rerun the script) in the same directory where we saved the matrix5.m MATLAB script file.

As long as you have an application registered with your computer that plays AVI video, you'll be able to double-click on the file from within your file manager and play the movie.

You should be able to loop the movie as well (for example, if you use QuickTime, you can choose Loop from the View menu off the menubar).

The movie should play as it does here:



and most embedded video players let us loop the video by right-mouse clicking on it and choosing Loop from the menu that appears.

Of course, many simulations have hundreds or thousands of time steps as the temporal resolution increases or the temporal extent expands.

We can use conditional logic to select the frames we want to write out to our movies.

To do so, we would add a frame_number variable by typing:
frame_number = 0
and then increment it each frame at bottom of the timestep loop by typing:
frame_number = frame_number + 1
just before the end statement that ends our loop statements.

We would also add a condition around the writeVideo command by updating our code to:
if mod(frame_number,2) == 0
    frame = getframe(gcf)
    writeVideo(v,frame)
end
and the movie would only write out every other frame.

The mod operator divides the integer (2) that appears as the second parameter into the variable (frame_number) that proceeds it to evaluate the remainder of the division. This is more generally called a modulus operation.

The remainder will only be 0 if the frame_number variable's current value is an exact multiple of the integer.

In this case, when frame_number is 0, 2, 4, 6, 8, etc.

If we chose an integer of 5, we'd only write frames 0, 5, 10, 15, etc. to the movie.

Here's a good final version of the script for you to use to compare to yours:
T = [14.9 15.0 15.2 15.4; 14.2 14.3 14.5 14.7; 13.4 13.69 13.9 14.2]
T(:,:,2) = [15.001 15.14 15.298 15.4; 14.38 14.407 14.65 14.7; 13.516 13.8031 14.0110 14.2]
T(:,:,3) = [15.121 15.3 15.39 15.91; 14.449 14.129 14.789 14.95; 13.638 13.51 14.209 14.449]
T(:,:,4) = [15.32 15.297 15.11 15.51; 14.208 14.178 14.119 15.57; 13.745 14.259 14.297 14.149]
T(:,:,5) = [15.28 15.22 15.582 15.783; 14.656 14.216 14.37 15.59; 13.571 14.357 14.374 14.256]
T(:,:,6) = [15.395 15.401 15.803 15.805; 14.793 14.244 15.46 15.20; 13.685 14.443 14.444 14.793]

time = [0,1,2,3,4,5]

frame_number = 0

v = VideoWriter('temperature.avi')
v.FrameRate = 2
open(v);

for time=1:6
    pcolor(T(:,:,time))
    
    xlabel('Longitude')
    ylabel('Latitude')
    title('Temperature change for all locations','FontSize', 18)   
    shading interp
    colormap jet
    axis([1 4 1 3])
    caxis([13.4 16])
    
    if mod(frame_number,2) == 0
        frame = getframe(gcf)
        writeVideo(v,frame)
    end
    
    frame_number = frame_number + 1
end

close(v)
We can of course gain benefit from reviewing previous modules. They are all linked here for our convenience:

Introduction
Primer 1
Primer 2
Primer 3
Primer 4
Primer 5
Primer 6