This document will (hopefully) show you everything that you need to know to be able to process your SPINS outputs using python (why python? Because it's not MATLAB). This tutorial will assume that you have a basic understanding of python syntax.
To begin, we import some useful packages. Base python is fairly bare-bones, but you'll find that there's a package for almost anything that you want.
In [1]:
%matplotlib inline
# Tells the system to plot in-line, only necessary for iPython notebooks,
# not regular command-line python
import numpy as np
import os
import sys
import matplotlib.pyplot as plt
import time
In [2]:
# Now that we have our packages, we need data. The file 'make_2d_data.py' will
# generate a sample data set. Let's run that now (may take a minute)
execfile('make_2d_data.py')
If we want to use our shiny python scripts, we'll need to import them too.
In [2]:
import spinspy as spy
import matpy as mp
If we want a quick man-page style summary, we can call
help(spy). We can also callhelp(spy.<func>)for more information on the function<func>. Since the data that we're looking at is in a different directory, let's specify that now.Note: This means that you don't need to be in the same directory as your data.
In [5]:
help(spy.set_path)
print('=======')
print('=======')
print('=======')
help(spy)
spy.set_path('Data/2d')
Now that we have all of our tools, let's start doing! Let's see what we have first.
In [6]:
ls Data/2d
We have q (potential vorticity, this is a QG example). Let's read and plot our initial q field.
In [7]:
q = spy.reader('q', 0, [0,-1], [0,-1])
What did that just do? Let's break it down and look at the inputs.
'q': This tells the function which variable to load (in this case, q)0: This is the index, so we will load q.0.[0,-1]: The x-range to load. This is shorthand and is equivalent to ':' from MATLAB.[0,-1]: The y-rangeHere we have loaded the entire thing. Alternatively, you could have given a single value or a list of indices. That is, giving
0would take the first slice,[0,100]takes the first 100 elements, and[0,2,4,6]takes the first, third, fifth, and, seventh elements.Lazy loading had also been implemented so that
q=spy.reader('q',0)would have also worked.
In [8]:
q.shape
Out[8]:
Note that this is ordered as (Nx,Ny). If we had wanted MATLAB style ordering (Ny,Nx), we could have used the optional argument
ordering = 'matlab'(useful for some plotting). The default isordering = 'natural'(useful because it feels right).
To begin, let's load in our grid. Since we aren't dealing with mapped grids, we only need vectors (the default behaviour).
In [11]:
x,y = spy.get_grid()
print('The shape of x is {0} and the shape of y is {1}'.format(x.shape,y.shape))
Perfect, now we have our grid vectors. We can also load in grid information, such as the domain size and limits. This is stored in a class that has a method called
display. These are illustrated below.
In [12]:
data = spy.get_params()
print(data.Nx,data.Ny,data.Nz)
print('---')
data.display()
We now have our grid vectors and potential vorticity loaded into memory, so it's time to try some plotting! A standard plotting library in python is matplotlib, which replicates many of MATLAB's 2D plotting functions. For example, here we have a pcolor and contour plot.
In [16]:
q = spy.reader('q', 10)
In [17]:
plt.figure(1)
t0 = time.clock()
plt.contour(x,y,q.T) # Transpose for plotting order
t1 = time.clock()
print('Time to plot: {0:1.2e}'.format(t1-t0))
plt.title('q');
plt.xlabel('x');
plt.ylabel('y');
In [20]:
plt.figure(2)
t0 = time.clock()
plt.pcolor(x,y,q.transpose()); # Regrettably, the default colormap is still jet...
t1 = time.clock()
print('Time to plot: {0:1.2e}'.format(t1-t0))
plt.colorbar()
plt.title('Height Field');
plt.xlabel('x');
plt.ylabel('y');
In [21]:
plt.figure(3)
t0 = time.clock()
plt.pcolormesh(x,y,q.T, cmap='darkjet') # So we made darkjet!
t1 = time.clock()
print('Time to plot: {0:1.2e}'.format(t1-t0))
plt.colorbar()
plt.title('Height Field')
plt.xlabel('x')
plt.ylabel('y')
plt.axis('tight')
plt.show()
We've just seen three examples of 2D plots:
contour,pcolor, andpcolormesh(contourfalso exists). In general, if you'll be working with high resolution rectangular grids, choosepcolormeshoverpcoloras it is cheaper on memory and time. The time taken for each plot was printed when you made the plots and pcolormesh was significantly faster! (Note: pcolormesh will not work for mapped grids)Also, both
pcolorandpcolormeshhave the unfortunate habit of adding extra white space, so you will often need to specify the axis limits or call plt.axis('tight')Most MATLAB colour maps are also available in matplotlib, you just need to set the optional argument
cmap='colourmap_name'. The package matpy provides darkjet.
In [62]: