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")
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:
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)
$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)
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)
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)
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)
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)
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')
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--')
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);
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);
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)
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]);
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()
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})
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
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)
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()