Matplotlib - Plotting in Python

Author: Steven Christe

Matplotlib is the main library for 2D (with some support for 3D) plotting in Python. It produces publication quality figures in a variety of hardcopy formats and interactive environments across platforms. Between Numpy and Matplotlib, much of MATLAB's functionality can be replaced with Python.

In this tutorial will only consider plotting with the pyplot formalism

This ipython notebook file can be found at

or can be viewed (if you don't have ipython installed) here

In [1]:
%matplotlib inline
In [8]:
import matplotlib # only need to get matplotlib version
import numpy as np
import sys # only need to get python version
In [9]:
print("Python version: " + sys.version)
print("Matplotlib version: " + matplotlib.__version__)
print("Numpy version: " + np.__version__)
Python version: 2.7.6 |Anaconda 1.8.0 (x86_64)| (default, Jan 10 2014, 11:23:15) 
[GCC 4.0.1 (Apple Inc. build 5493)]
Matplotlib version: 1.3.1
Numpy version: 1.8.1
In [2]:
import matplotlib.pyplot as plt
In [3]:
plt.ylabel('some numbers')

Plotting x-y pairs and quickly setting the x and y range

In [4]:
plt.plot([1,2,3,4], [1,4,9,16], 'ro')
plt.axis([0, 6, 0, 20])
In [5]:
plt.plot([1,2,3,4], [1,4,9,16], 'ro-', label = 'data 1')
plt.plot([1,2,3,4], [1,2,3,4], 'bo', label='data 2')
plt.axis([0, 6, 0, 20])
In [6]:
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)

If you want more than just one plot create a figure

In [7]:
plt.plot(t1, f(t1), 'bo', t2, f(t2), 'k')

plt.plot(t2, np.cos(2*np.pi*t2), 'r--')
In [8]:
plt.plot(t1, f(t1), 'bo', t2, f(t2), 'k')

plt.plot(t2, np.cos(2*np.pi*t2), 'r--')

plt.plot(t1, f(t1), 'bo', t2, f(t2), 'k')

plt.plot(t2, np.cos(2*np.pi*t2), 'r--')
In [9]:
mu, sigma = 100, 15
x = mu + sigma * np.random.randn(10000)

# the histogram of the data
n, bins, patches = plt.hist(x, 50, normed=1, facecolor='g', alpha=0.75)

plt.title('Histogram of IQ')
plt.text(60, .025, r'$\mu=100,\ \sigma=15$')
plt.axis([40, 160, 0, 0.03])
In [10]:
import datetime
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import matplotlib.cbook as cbook

years    = mdates.YearLocator()   # every year
months   = mdates.MonthLocator()  # every month
yearsFmt = mdates.DateFormatter('%Y')

# load a numpy record array from yahoo csv data with fields date,
# open, close, volume, adj_close from the mpl-data/example directory.
# The record array stores python as an object array in
# the date column
datafile = cbook.get_sample_data('goog.npy')
r = np.load(datafile).view(np.recarray)

fig, ax = plt.subplots()
ax.plot(, r.adj_close, label='goog')

# format the ticks

datemin =, 1, 1)
datemax =, 1, 1)
ax.set_xlim(datemin, datemax)
plt.legend(loc='upper left')


# rotates and right aligns the x labels, and moves the bottom of the
# axes up to make room for them

Plotting Images

In [11]:
from matplotlib import cm
from numpy.random import randn

# Make plot with vertical (default) colorbar
fig, ax = plt.subplots()

data = np.clip(randn(250, 250), -1, 1)

cax = ax.imshow(data, interpolation='nearest', cmap=cm.coolwarm)
ax.set_title('Gaussian noise with vertical colorbar')

# Add colorbar, make sure to specify tick locations to match desired ticklabels
cbar = fig.colorbar(cax, ticks=[-1, 0, 1])['< -1', '0', '> 1'])# vertically oriented colorbar
In [12]:
# Make plot with horizontal colorbar
fig, ax = plt.subplots()

data = np.clip(randn(250, 250), -1, 1)

cax = ax.imshow(data, interpolation='nearest', cmap=cm.coolwarm)
ax.set_title('Gaussian noise with horizontal colorbar')

cbar = fig.colorbar(cax, ticks=[-1, 0, 1], orientation='horizontal')['Low', 'Medium', 'High'])# horizontal colorbar
In [13]:
import matplotlib.mlab as mlab
delta = 0.025
x = np.arange(-3.0, 3.0, delta)
y = np.arange(-2.0, 2.0, delta)
X, Y = np.meshgrid(x, y)
Z1 = mlab.bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
Z2 = mlab.bivariate_normal(X, Y, 1.5, 0.5, 1, 1)
# difference of Gaussians
Z = 10.0 * (Z2 - Z1)

Contour Plots

In [14]:
CS = plt.contour(X, Y, Z)
plt.clabel(CS, inline=1, fontsize=10)
plt.title('Simplest default with labels')
In [15]:
# Or you can use a colormap to specify the colors; the default
# colormap will be used for the contour lines

# plot the image
im = plt.imshow(Z, interpolation='bilinear', origin='lower', cmap=cm.gray, extent=(-3,3,-2,2))

# now overplot the contours
levels = np.arange(-3.0, 3.0, 0.5)
CS = plt.contour(Z, levels, origin='lower', linewidths=2, extent=(-3,3,-2,2))

plt.clabel(CS, levels ,inline=1, fmt='%1.1f', fontsize=14)

# make a colorbar for the contour lines
CB = plt.colorbar(CS, shrink=0.8, extend='both')

plt.title('Lines with colorbar')

# We can still add a colorbar for the image, too.
CBI = plt.colorbar(im, orientation='horizontal', shrink=0.8)

# This makes the original colorbar look a bit out of place,
# so let's improve its position.
#l,b,w,h = plt.gca().get_position().bounds
#ll,bb,ww,hh =[ll, b+0.1*h, ww, h*0.8])
In [16]:
from matplotlib.colors import LogNorm
from numpy.random import normal

#normal distribution center at x=0 and y=5
x = normal(0,1,100000)
y = normal(0,1,100000)+5

2d Histograms

In this example we will make the histogram in two different ways (1) by plotting a histogram and (2) by creating a 2d histogram and plotting it as an image

In [17]:
plt.hist2d(x, y, bins=[40,20])
x1,x2,y1,y2 = plt.axis()

lets do the same thing but make the heatmap ourselves

In [18]:
heatmap, xedges, yedges = np.histogram2d(x, y, bins=[20,40], range=[[x1,x2],[y1,y2]])
print(x1, x2, y1, y2)
print(xedges[0], xedges[-1], yedges[0],yedges[-1])
extent = [x1, x2, y1, y2]

plt.imshow(heatmap, extent=extent)
(-4.5097523174655798, 4.4561788934696418, 0.73603245574760745, 9.6659734902476195)
(-4.5097523174655798, 4.4561788934696418, 0.73603245574760745, 9.6659734902476195)

3d Plots

In [19]:
from mpl_toolkits.mplot3d.axes3d import Axes3D
/Users/schriste/anaconda/lib/python2.7/site-packages/mpl_toolkits/ UserWarning: Module _imaging was already imported from /Users/schriste/anaconda/lib/python2.7/site-packages/PIL/, but /Users/schriste/.local/lib/python2.7/site-packages is being added to sys.path
In [20]:
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)
In [21]:
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=-3.5, cmap=cm.coolwarm)
cset = ax.contour(X, Y, Z, zdir='x', offset=-3.5, cmap=cm.coolwarm)
cset = ax.contour(X, Y, Z, zdir='y', offset=2, cmap=cm.coolwarm)

ax.set_xlim3d(-3.5, 3.5);
ax.set_ylim3d(-2.5, 2.5);
ax.set_zlim3d(-3, 2);
In [22]:
fig = plt.figure(figsize=(12,6))

ax = fig.add_subplot(1,2,1, projection='3d')
ax.plot_surface(X, Y, Z, rstride=4, cstride=4, alpha=0.25)
ax.view_init(30, 45)

ax = fig.add_subplot(1,2,2, projection='3d')
ax.plot_surface(X, Y, Z, rstride=4, cstride=4, alpha=0.25)
ax.view_init(70, 30)