Matplotlib

Reference Documents

  • Matplotlib Tutorial by Nicolas P. Rougier

  • A slightly old (but not obsolete!) video by Mike Müller from 2012 with introduction to plotting capabilities of matplotlib [~2 hours]


In [ ]:
from IPython.display import YouTubeVideo
#YouTubeVideo("https://www.youtube.com/watch?v=P7SVi0YTIuE")
YouTubeVideo("P7SVi0YTIuE")

What is Matplotlib?

matplotlib is a library for making 2D plots of arrays in Python. It is capable of producing sophisticated 2D plots with high quality outputs.

matplotlib has some 3D plotting capabilities through mplot3d toolkit, but for sofisticated 3D visualization it is better to use different packages

matplotlib is conceptually divided into three parts:

  • the pylab interface is the set of functions provided by matplotlib.pylab which allow the user to create plots with code quite similar to MATLAB figure generating code.
  • The matplotlib API is the set of classes that do the heavy lifting, creating and managing figures, text, lines, plots and so on.
  • The backends are device-dependent drawing devices, aka renderers, that transform the frontend representation to hardcopy or a display device - not covered in this tutorial

Pyplot interface

Simple Plot


In [ ]:
%matplotlib inline 

import numpy as np
import matplotlib.pylab as plt

x = [2, 3, 5, 7, 11,13,16]
y = [4, 9, 5, 9, 1,3,4.5]
plt.plot(x, y)

Useful Syntax

plot(x,y) xlabel('string') # label the x-axis ylabel('string') # label the y-axis title('string') # write the title of the plot grid(true/false) # adds grid boxes savefig('fileName.type') # type can be png, ps, pdf, etc show() # display the graph on the screen xlim(xmin,xmax) # set/get the xlimits ylim(ymin,ymax) # set/get the ylimits hold(True/False) # to overlay figures on the same graph

Data for plotting

$t\in[0,4\pi]$, $s_1=\cos(x)$, $s_2=\frac{1}{2}\cos(x)+\frac{1}{2}\cos(3 x)$


In [ ]:
import math

t = np.linspace(0, 4*np.pi, 100)
s1 = np.cos(t)
s2 = 0.5*np.cos(t) + 0.25*np.cos(3*t)

Two plots on the same axes with labels


In [ ]:
plt.plot(t, s1)
plt.plot(t, s2)

# add labels
plt.xlabel('time (s)')
plt.ylabel('voltage (mV)')
plt.title('About as simple as it gets, folks')
# add grid
plt.grid(True)

Change linestyle

help for plot() function - line style options listed here


In [ ]:
# short form of linestyle specification
plt.plot(t, s1,'k-', linewidth=1)

# long form of linestyle specification
plt.plot(t, s2, linestyle='dashed',color='r', linewidth=1)

plt.xlabel('time (s)')
plt.ylabel('voltage (mV)')
plt.title('About as simple as it gets, folks')
plt.grid(True)

Add Legend

can use LaTeX in text


In [ ]:
x = np.linspace(0, 2*np.pi, 300)
y1 = np.sin(x)
y2 = np.sin(x**2)

# add labels to the curves, can use LaTeX 
plt.plot(x, y1, label=r'$\sin(x)$')
plt.plot(x, y2, label=r'$\sin(x^2)$')
plt.title('functions: $\sin(x)$ and $\sin(x^2)$')

plt.xlabel('x')
plt.ylabel('y')
plt.grid()

# add legend; loc=0 "best" placement
plt.legend(loc=0)

Change Axes Limits


In [ ]:
# add labels to the curves, can use LaTeX 
plt.plot(x, y1, label=r'$\sin(x)$')
plt.plot(x, y2, label=r'$\sin(x^2)$')
plt.title('functions: $\sin(x)$ and $\sin(x^2)$')

plt.xlabel('x')
plt.ylabel('y')
plt.grid()

# change axes limits
plt.xlim(-0.1,6.5)
plt.ylim(-1.1,1.1)

# add legend; loc=0 "best" placement
plt.legend(loc=0)

Save Figure to File

savefig(filename.ext) saves current figure into a file (help)


In [ ]:
# add labels to the curves, can use LaTeX 
plt.plot(x, y1, label=r'$\sin(x)$')
plt.plot(x, y2, label=r'$\sin(x^2)$')
plt.title('functions: $\sin(x)$ and $\sin(x^2)$')

plt.xlabel('x')
plt.ylabel('y')
plt.grid()

# change axes limits
plt.xlim(-0.1,6.5)
plt.ylim(-1.1,1.1)

# add legend; loc=0 "best" placement
plt.legend(loc=0)

# save figure to a PDF file
plt.savefig('sin_legend_plot.pdf')

Multiple Figures on the Same Plot

subplot(nrows, ncols, plot_number) creates a subplot axes positioned by the given grid definition (help)


In [ ]:
def f(t):
    return np.exp(-t) * np.cos(2*np.pi*t)

t1 = np.arange(0.0, 5.0, 0.1)
t2 = np.arange(0.0, 5.0, 0.02)

# create figure
plt.figure(1)
# first subplot - 2,1,1: 2 rows, 1 column, first plot
plt.subplot(2,1,1)
# plot both data with a single plot function call
# first plot filled circles, then solid black line
plt.plot(t1, f(t1), 'bo', t2, f(t2), 'k')

# can use a simpler form, without commas - 212: 2 rows, 1 column, second plot
plt.subplot(212)
plt.plot(t2, np.cos(2*np.pi*t2), 'r--')

Annotating Text

Default options

In [ ]:
t = np.arange(0.0, 5.0, 0.01)
s = np.cos(2*np.pi*t)
# use 'lw' instead of 'linewidth'
plt.plot(t, s, lw=1.5)

# put annotation on to plot
plt.annotate('local max of $\cos(t)$', \
             xy=(2, 1), \
             xytext=(3, 1.5),\
             arrowprops=dict(facecolor='black'))
# change y limits for y-axis
plt.ylim(-2,2);
Fine controll of text and arrow appearance

In [ ]:
t = np.arange(0.0, 5.0, 0.01)
s = np.cos(2*np.pi*t)
# use 'lw' instead of 'linewidth'
plt.plot(t, s, lw=1.5)

# put annotation on to plot
# fine control of text and arrow properties
plt.annotate('local max of $\cos(t)$', \
             xy=(2, 1), \
             xytext=(3, 1.5), \
             arrowprops=dict(facecolor='black', shrink=0.05,width=1,headwidth=6), \
            fontsize='x-large',fontname="serif")

# change y limits for y-axis
plt.ylim(-2,2);

Plot with Fill


In [ ]:
t = np.arange(0.0, 1.01, 0.01)
s = np.sin(2*2*np.pi*t)

plt.fill(t, s*np.exp(-5*t), 'r')
plt.grid(True)

Histogram


In [ ]:
mu, sigma = 100, 15
x = mu + sigma * np.random.randn(10000)

# the histogram of the data
# alpha - is the transparency of the plot
n, bins, patches = plt.hist(x,50, normed=True, facecolor='g', alpha=.65)

plt.xlabel('Smarts')
plt.ylabel('Probability')
plt.title('Histogram of IQ')
plt.text(50, .0275, r'$\mu=100,\ \sigma=\frac{1}{\sqrt{15}}$', fontsize='x-large')
plt.axis([40, 160, 0, 0.031]);

Log Plot


In [ ]:
plt.subplots_adjust(hspace=0.4)
t = np.arange(0.01, 20.0, 0.01)

# log y axis
plt.subplot(221)
plt.semilogy(t, np.exp(-t/5.0))
plt.title('semilogy')
plt.grid(True)

# log x axis
plt.subplot(222)
plt.semilogx(t, np.sin(2*np.pi*t))
plt.ylim(-1.1,1.1)
plt.title('semilogx')
plt.grid(True)

# log x and y axis
plt.subplot(223)
plt.loglog(t, 20*np.exp(-t/10.0), basex=2)
plt.grid(True)
plt.title('loglog base 4 on x')

# with errorbars: clip non-positive values
plt.subplot(224)
# set logarithmic axes
plt.xscale("log", nonposx='clip')
plt.yscale("log", nonposy='clip')

x = 10.0**np.linspace(0.0, 2.0, 20)
y = x**2.0
plt.errorbar(x, y, xerr=0.1*x, yerr=5.0+0.75*y)
plt.ylim(ymin=0.1)
plt.title('Errorbars go negative')

# will need it later
fig_log_plots=plt.gcf()

Pie Chart


In [ ]:
# make a square figure and axes
plt.figure(1, figsize=(6,6))
plt.axes([0.1, 0.1, 0.8, 0.8])
labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
fracs = [15,30,45, 10]
explode=(0, 0.1, 0, 0)

plt.pie(fracs, explode=explode, labels=labels, autopct='%1.1f%%', shadow=True)
plt.title('Raining Hogs and Dogs', bbox={'facecolor':'0.9', 'pad':5})

Contour Plot and Colorbar


In [ ]:
def f(x,y):
    return (1-x/2+x**5+y**3)*np.exp(-x**2-y**2)

n = 256
x = np.linspace(-3,3,n)
y = np.linspace(-3,3,n)
X,Y = np.meshgrid(x,y)

plt.axes([0.025,0.025,0.95,0.95])

plt.contourf(X, Y, f(X,Y), 10, alpha=.75, cmap=plt.cm.hot)
plt.colorbar()

C = plt.contour(X, Y, f(X,Y), 10, colors='black', linewidth=.5)
plt.clabel(C, inline=1, fontsize=10)
plt.xticks([])
plt.yticks([])

If you do not know how to make a specific plot, the best place to go is matplotlib gallery.

It contains a large number of plots together with the Python souces files which you can download and adjust to your needs.


In [ ]:
# I just picked one to try:
%load http://matplotlib.org/mpl_examples/api/sankey_demo_rankine.py

Matplotlib API


In [ ]:
%matplotlib inline
import matplotlib.pylab as plt
import numpy as np

def f(t):
    return np.exp(-t) * np.cos(2*np.pi*t)

t1 = np.arange(0.0, 5.0, 0.1)
t2 = np.arange(0.0, 5.0, 0.02)

# create figure
fig=plt.figure(1)
# add subplot to the figure, retunrns Axes object
ax1=fig.add_subplot(2,1,1)
# plot both data with a single plot function call
# first plot filled circles, then solid black line
lines11,lines12,=ax1.plot(t1, f(t1), 'bo', t2, f(t2), 'k')

# can use a simpler form, without commas - 212: 2 rows, 1 column, second plot
ax2=fig.add_subplot(212)
lines22,=ax2.plot(t2, np.cos(2*np.pi*t2), 'r--')
plt.show()

In [ ]:
lines22.set_linewidth(1)
lines22.set_linestyle(':')
ax2.set_ylim(-1.5,1.5)
ax1.grid(True)
fig

In [ ]:
fig_log_plots.savefig('log_plots.png')

In [ ]:
fig.savefig('two_plots.png',dpi=600)

3D plotting with mplot3d


In [ ]:
from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt
from matplotlib import cm

fig = plt.figure()
ax = fig.gca(projection='3d')
X, Y, Z = axes3d.get_test_data(0.05)

ax.plot_surface(X, Y, Z, rstride=8, cstride=8, alpha=0.3)
cset = ax.contourf(X, Y, Z, zdir='z', offset=-100, cmap=cm.coolwarm)
cset = ax.contourf(X, Y, Z, zdir='x', offset=-40, cmap=cm.coolwarm)
cset = ax.contourf(X, Y, Z, zdir='y', offset=40, cmap=cm.coolwarm)

ax.set_xlabel('X')
ax.set_xlim(-40, 40)
ax.set_ylabel('Y')
ax.set_ylim(-40, 40)
ax.set_zlabel('Z')
ax.set_zlim(-100, 100)

plt.show()

A final note

Since we often need to use numpy + matplotlib (+ SciPy + others) at the same time, we can import all of these modules at once using a single command. Instead of:

    import numpy as np
    import matplotlib.pyplot as plt
    %matplotlib inline

etc., just use:

    %pylab inline