Introduction to Python, Numpy, and Matplotlib

You will start almost every script with import statements. They import libraries and modules that you will use. Some of the most common libraries are NumPy (numerics), SymPy (symbolics), Matplotlib (plotting), and Pandas (time series and data). The syntax is as follows

If you want to import the entire library, you do this:


In [ ]:
import numpy

If you want to import a library and give it a different name for ease (you will see why you want to do this in a little bit) you simply use the "as" command


In [ ]:
import numpy as np

If you want to import just a specific module from a libary, you would do this:


In [ ]:
from numpy import cos

or...


In [ ]:
from numpy import cos as c

Now I have imported the cosine function from the numpy library and named it c (usually would just use "cos", but just an example). So what do I do with this? Simple, use "c" as the cosine function, giving it input within a set of parantheticals


In [ ]:
c(180*2*np.pi/360) # cosine of 180 degrees

In [ ]:
c(0)

Typically, would utilize the numpy library like this, calling the cosine function from the library with this syntax:


In [ ]:
np.cos(0)

So instead of calling "numpy" everytime you want to use one of the modules, you just call "np". This makes it easier when you want to use plotting functions from matplotlib that might have long names. For example,


In [ ]:
from matplotlib import pyplot as plt

In [ ]:
import matplotlib.pyplot as plt #same thing

You will find yourself importing many different libraries in more complicated scripts, that employ data processing, reading, and plotting.

If you don't want to use the "np" or "plt" extensions, you can import everything from a library using this command:


In [ ]:
from numpy import *

Imports all of numpy's modules and you can use "cos" just by itself


In [ ]:
cos(0)

You will most likely use Numpy and Matplotlib the most of any libraries (maybe Pandas as well)

NUMPY

Some real basic examples in numpy, you will get experience fast in manipulating this library for your specific tasks

Make an array from a range of numbers


In [ ]:
x = np.arange(40) # default is a range from 0 to the input value by 1
y = np.arange(0,40,2) # can specify the increment
z = np.arange(0,20+1,+1) #makes the range go TO 20, by default will stop one short of the given value (i.e. 20 values in the array)
print z

In [ ]:
b = y.reshape(4,5) # reshape the array into a 3x7 2d array
print b

In [ ]:
a = y.reshape(2,2,5) # 3d array
print a

In [ ]:
>>> a = array( [20,30,40,50] )
>>> b = arange( 4 )
>>> b
array([0, 1, 2, 3])
>>> c = a-b
>>> c
array([20, 29, 38, 47])
>>> b**2
array([0, 1, 4, 9])
>>> 10*sin(a)
array([ 9.12945251, -9.88031624,  7.4511316 , -2.62374854])
>>> a<35

Indexing

Arrays are easy to maneuver as well, indexing is very similar to other languages. It is 0 based FYI


In [ ]:
print a[2]
print a[1]
print a[0]

In [ ]:
print a[-1] # print the last entry in the array

In [ ]:
print a[0:2]

In [ ]:
print a[: :-1] #print a in reverse

In [ ]:
a.shape # what are the dimensions of the array? 4X1

In [ ]:
y = np.arange(0,40,2)
b = y.reshape(2,2,5)
b.shape # 3 dimensional

For Loops


In [ ]:
y = np.arange(0,40,2)
for numbers in y:
    print numbers**2  # just print the square of each value
    
#### INDENTATION IS IMPORTANT!! Whatever is indented will be included in the for loop

It's even easier than that thought, You can do for loops in just ONE LINE!


In [ ]:
test = [str(nums)+'*' for nums in y] # make a new array with the numbers from y with an added asteristic. Now an array of strings
print test

If you just want to mathematically alter the elements of an array, can just use array mathematics


In [ ]:
y*2

In [ ]:
(y*2 + 2)**3

Functions

Lets say you want to make a unique manipulation of an array, or read in data files multiple times in a script, well you may think, "A function would be really nice right now". Python has those too! Here is the syntax


In [ ]:
### This is a stupid example, but you get the idea
def pass_to(filename,extension):
    """ This is a docstring, which tells the user what the function is for. Often, will define what the inputs and outputs are
    Inputs: Filename-string of the desired file to be read in
            extension-string 
    Output: Return the array of the read in file """
    a=np.genfromtext(filename+extension)
    print 'Filename is: '+filename+'.'+extension
    return a

MATPLOTLIB

Introduction to basic plotting in python

Introduction

Matplotlib is an excellent 2D and 3D graphics library for generating scientific figures. Some of the many advantages of this library includes:

  • Easy to get started
  • Support for $\LaTeX$ formatted labels and texts
  • Great control of every element in a figure, including figure size and DPI.
  • High-quality output in many formats, including PNG, PDF, SVG, EPS.
  • GUI for interactively exploring figures and support for headless generation of figure files (useful for batch jobs).

One of the of the key features of matplotlib that I would like to emphasize, and that I think makes matplotlib highly suitable for generating figures for scientific publications is that all aspects of the figure can be controlled programmatically. This is important for reproducibility, convenient when one need to regenerate the figure with updated data or changes its appearance.

More information at the Matplotlib web page: http://matplotlib.org/

To get started using matplotlib in python, you must "import" the library using:


In [ ]:
from pylab import *

Or you can import pyplot directly from the matplotlib library (typically what I do, since pyplot is what I use the most:


In [ ]:
import matplotlib.pyplot as plt

Example:


In [ ]:
%pylab inline  
# this just insets the plots into ipython notebook, won't use this in a normal python script

In [ ]:
import numpy as np
plt.subplot(1,2,1)
x = np.arange(0,10,1)
y = x**2
plt.plot(x,y,'r')
plt.title('Example Plot 1')
plt.xlabel('x')
plt.ylabel('y')
plt.subplot(1,2,2)
plt.plot(y,x,'b--')
plt.title('Example Plot 2')
plt.xlabel('y')
plt.ylabel('x')
plt.show()

The matplotlib object-oriented API

The main idea with object-oriented programming is to have objects that one can apply functions and actions on, and no object or program states should be global (such as the MATLAB-like API). The real advantage of this approach becomes apparent when more than one figure is created, or when a figure contains more than one subplot.

To use the object-oriented API we start out very much like in the previous example, but instead of creating a new global figure instance we store a reference to the newly created figure instance in the fig variable, and from it we create a new axis instance axes using the add_axes method in the Figure class instance fig.


In [ ]:
fig = plt.figure()

axes = fig.add_axes([0.1, 0.1, 0.8, 0.8]) # left, bottom, width, height (range 0 to 1)

axes.plot(x, y, 'r')

axes.set_xlabel('x')
axes.set_ylabel('y')
axes.set_title('title');

Although a little bit more code is involved, the advantage is that we now have full control of where the plot axes are place, and we can easily add more than one axis to the figure.


In [ ]:
fig = plt.figure()

axes1 = fig.add_axes([0.1, 0.1, 0.8, 0.8]) # main axes
axes2 = fig.add_axes([0.2, 0.5, 0.4, 0.3]) # inset axes

# main figure
axes1.plot(x, y, 'r')
axes1.set_xlabel('x')
axes1.set_ylabel('y')
axes1.set_title('title')

# insert
axes2.plot(y, x, 'g')
axes2.set_xlabel('y')
axes2.set_ylabel('x')
axes2.set_title('insert title');

If we don't care to be explicit about where our plot axes are placed in the figure canvas, then we can use one of the many axis layout managers in matplotlib. My favorite is subplots, which can be used like this:


In [ ]:
fig, axes = plt.subplots()

axes.plot(x, y, 'r')
axes.set_xlabel('x')
axes.set_ylabel('y')
axes.set_title('title');

In [ ]:
fig, axes = plt.subplots(nrows=1, ncols=2)

for ax in axes:
    ax.plot(x, y, 'r')
    ax.set_xlabel('x')
    ax.set_ylabel('y')
    ax.set_title('title');

That was easy, but it isn't so pretty with overlapping figure axes and labels, right?

We can deal with that by using the fig.tight_layout method, which automatically adjusts the positions of the axes on the figure canvas so that there is no overlapping content:


In [ ]:
fig, axes = plt.subplots(nrows=1, ncols=2)

for ax in axes:
    ax.plot(x, y, 'r')
    ax.set_xlabel('x')
    ax.set_ylabel('y')
    ax.set_title('title')
    
fig.tight_layout()

In [ ]:
fig = plt.figure(figsize=(8,4), dpi=100)
# Or you can pass to subplots
fig, axes = plt.subplots(figsize=(12,3))

axes.plot(x, y, 'r')
axes.set_xlabel('x')
axes.set_ylabel('y')
axes.set_title('title');

Very easy to save figures as well


In [ ]:
fig.savefig("filename.png")

# or

fig.savefig("filename.png", dpi=200)

For a paper, use PDF whenever possible for best possible format (in my opinion, although I think this is generally accepted)


In [ ]:
ax.plot(x, x**2, label="curve1")
ax.plot(x, x**3, label="curve2")
ax.legend();

Line and marker styles

To change the line width we can use the linewidth or lw keyword argument, and the line style can be selected using the linestyle or ls keyword arguments:


In [ ]:
fig, ax = subplots(figsize=(12,6))

ax.plot(x, x+1, color="blue", linewidth=0.25)
ax.plot(x, x+2, color="blue", linewidth=0.50)
ax.plot(x, x+3, color="blue", linewidth=1.00)
ax.plot(x, x+4, color="blue", linewidth=2.00)

# possible linestype options ‘-‘, ‘–’, ‘-.’, ‘:’, ‘steps’
ax.plot(x, x+5, color="red", lw=2, linestyle='-')
ax.plot(x, x+6, color="red", lw=2, ls='-.')
ax.plot(x, x+7, color="red", lw=2, ls=':')

# custom dash
line, = ax.plot(x, x+8, color="black", lw=1.50)
line.set_dashes([5, 10, 15, 10]) # format: line length, space length, ...

# possible marker symbols: marker = '+', 'o', '*', 's', ',', '.', '1', '2', '3', '4', ...
ax.plot(x, x+ 9, color="green", lw=2, ls='*', marker='+')
ax.plot(x, x+10, color="green", lw=2, ls='*', marker='o')
ax.plot(x, x+11, color="green", lw=2, ls='*', marker='s')
ax.plot(x, x+12, color="green", lw=2, ls='*', marker='1')

# marker size and color
ax.plot(x, x+13, color="purple", lw=1, ls='-', marker='o', markersize=2)
ax.plot(x, x+14, color="purple", lw=1, ls='-', marker='o', markersize=4)
ax.plot(x, x+15, color="purple", lw=1, ls='-', marker='o', markersize=8, markerfacecolor="red")
ax.plot(x, x+16, color="purple", lw=1, ls='-', marker='s', markersize=8, 
        markerfacecolor="yellow", markeredgewidth=2, markeredgecolor="blue");

Control over axis apperance

The appearance of the axes is an important aspect of a figure that we often need to modify to make a publication quality graphics. We need to be able to control where the ticks and labels are placed, modify the font size and possibly the labels used on the axes. In this section we will look at controling those properties in a matplotlib figure.

Plot range

The first thing we might want to configure is the ranges of the axes. We can do it using the set_ylim and set_xlim methods in the axis object, or axis('tight') for automatrically getting "tightly fitted" axes ranges.


In [ ]:
fig, axes = subplots(1, 3, figsize=(12, 4))

axes[0].plot(x, x**2, x, x**3)
axes[0].set_title("default axes ranges")

axes[1].plot(x, x**2, x, x**3)
axes[1].axis('tight')
axes[1].set_title("tight axes")

axes[2].plot(x, x**2, x, x**3)
axes[2].set_ylim([0, 60])
axes[2].set_xlim([2, 5])
axes[2].set_title("custom axes range");

Placement of ticks and custom tick labels

We can explicitly determine where we want the axis ticks using the set_xticks and set_yticks, which both takes a list of values for where on the axis the ticks are to be placed. We can also use the functions set_xticklabels and set_yticklabels to provide a list of custom text labels for each tick location:


In [ ]:
fig, ax = subplots(figsize=(10, 4))

ax.plot(x, x**2, x, x**3, lw=2)

ax.set_xticks([1, 2, 3, 4, 5])
ax.set_xticklabels([r'$\alpha$', r'$\beta$', r'$\gamma$', r'$\delta$', r'$\epsilon$'], fontsize=18)

yticks = [0, 50, 100, 150]
ax.set_yticks(yticks)
ax.set_yticklabels(["$%.1f$" % y for y in yticks], fontsize=18); # use LaTeX formatted labels

Turning on and off grid lines


In [ ]:
fig, axes = subplots(1, 2, figsize=(10,3))

# default grid appearance
axes[0].plot(x, x**2, x, x**3, lw=2)
axes[0].grid(True)

# custom grid appearance
axes[1].plot(x, x**2, x, x**3, lw=2)
axes[1].grid(color='b', alpha=0.5, linestyle='dashed', linewidth=0.5)

Twin axes

Sometimes it is useful to have dual x or y axes in a figure, for example when plotting curves with differnt units together. Matplotlib supports this with the twinx and twiny functions:


In [ ]:
fig, ax1 = subplots()

ax1.plot(x, x**2, lw=2, color="blue")
ax1.set_ylabel(r"area $(m^2)$", fontsize=18, color="blue")
for label in ax1.get_yticklabels():
    label.set_color("blue")
    
ax2 = ax1.twinx()
ax2.plot(x, x**3, lw=2, color="red")
ax2.set_ylabel(r"volume $(m^3)$", fontsize=18, color="red")
for label in ax2.get_yticklabels():
    label.set_color("red")

Other 2D plot styles

In addition to the function plot, there are a number of other functions for generating different kind of plots. See the matplotlib plot gallery for a complete list of avaiable plot types: http://matplotlib.org/gallery.html. Some of the more useful ones are show below:


In [ ]:
n = array([0,1,2,3,4,5])
xx = np.linspace(-0.75, 1., 100)
fig, axes = subplots(1, 4, figsize=(12,3))

axes[0].scatter(xx, xx + 0.25*randn(len(xx)))

axes[1].step(n, n**2, lw=2)

axes[2].bar(n, n**2, align="center", width=0.5, alpha=0.5)

axes[3].fill_between(x, x**2, x**3, color="green", alpha=0.5);

In [ ]:
# polar plot using add_axes and polar projection
fig = plt.figure()
ax = fig.add_axes([0.0, 0.0, .6, .6], polar=True)
t = linspace(0, 2 * pi, 100)
ax.plot(t, t, color='blue', lw=3);

Figures with Multiple Subplots and Insets


In [ ]:
fig = plt.figure()
ax1 = plt.subplot2grid((3,3), (0,0), colspan=3)
ax2 = plt.subplot2grid((3,3), (1,0), colspan=2)
ax3 = plt.subplot2grid((3,3), (1,2), rowspan=2)
ax4 = plt.subplot2grid((3,3), (2,0))
ax5 = plt.subplot2grid((3,3), (2,1))
fig.tight_layout()

Colormap and contour figures

Colormaps and contour figures are useful for plotting functions of two variables. In most of these functions we will use a colormap to encode one dimension of the data. There is a number of predefined colormaps, and it is relatively straightforward to define custom colormaps. For a list of pre-defined colormaps, see:

http://www.scipy.org/Cookbook/Matplotlib/Show_colormaps


In [ ]:
alpha = 0.7
phi_ext = 2 * pi * 0.5

def flux_qubit_potential(phi_m, phi_p):
    return 2 + alpha - 2 * cos(phi_p)*cos(phi_m) - alpha * cos(phi_ext - 2*phi_p)

In [ ]:
phi_m = linspace(0, 2*pi, 100)
phi_p = linspace(0, 2*pi, 100)
X,Y = meshgrid(phi_p, phi_m)
Z = flux_qubit_potential(X, Y).T

Pcolor


In [ ]:
fig, ax = subplots()

p = ax.pcolor(X/(2*pi), Y/(2*pi), Z, cmap=cm.RdBu, vmin=abs(Z).min(), vmax=abs(Z).max())
cb = fig.colorbar(p)

imshow


In [ ]:
fig, ax = subplots()

im = imshow(Z, cmap=cm.RdBu, vmin=abs(Z).min(), vmax=abs(Z).max(), extent=[0, 1, 0, 1])
im.set_interpolation('bilinear')

cb = fig.colorbar(im)

contour


In [ ]:
fig, ax = subplots()

cnt = contour(Z, cmap=cm.RdBu, vmin=abs(Z).min(), vmax=abs(Z).max(), extent=[0, 1, 0, 1])

3D figures

To use 3D graphics in matplotlib, we first need to create an axes instance of the class Axes3D. 3D axes can be added to a matplotlib figure canvas in exactly the same way as 2D axes, but a conventient way to create a 3D axis instance is to use the projection='3d' keyword argument to the add_axes or add_subplot functions.


In [ ]:
from mpl_toolkits.mplot3d.axes3d import Axes3D

fig = plt.figure(figsize=(14,6))

# `ax` is a 3D-aware axis instance, because of the projection='3d' keyword argument to add_subplot
ax = fig.add_subplot(1, 2, 1, projection='3d')

p = ax.plot_surface(X, Y, Z, rstride=4, cstride=4, linewidth=0)

# surface_plot with color grading and color bar
ax = fig.add_subplot(1, 2, 2, projection='3d')
p = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.coolwarm, linewidth=0, antialiased=False)
cb = fig.colorbar(p, shrink=0.5)

Coutour plots with projections


In [ ]:
fig = plt.figure(figsize=(8,6))

ax = fig.add_subplot(1,1,1, projection='3d')

ax.plot_surface(X, Y, Z, rstride=4, cstride=4, alpha=0.25)
cset = ax.contour(X, Y, Z, zdir='z', offset=-pi, cmap=cm.coolwarm)
cset = ax.contour(X, Y, Z, zdir='x', offset=-pi, cmap=cm.coolwarm)
cset = ax.contour(X, Y, Z, zdir='y', offset=3*pi, cmap=cm.coolwarm)

ax.set_xlim3d(-pi, 2*pi);
ax.set_ylim3d(0, 3*pi);
ax.set_zlim3d(-pi, 2*pi);

Basemap


In [ ]:

Further reading

ALSO UTILIZE STACKOVERFLOW.COM WHEN YOU HAVE ISSUES!


In [ ]: