Contour plots
Contour plots allow us to project a third dimension of data down onto an X, Y axis, be it a functional relationship between two dimensions of data or some decision threshold of a given model.
But before we can start plotting this third dimension of data, we have to figure out how to calculate it.
Meshgrid
Say we’ve got two simple vectors, x
and y
.
%pylab inline
x = np.linspace(0, 10, 5)
y = np.linspace(0, 1, 4)
Populating the interactive namespace from numpy and matplotlib
x
has length 5
and y
has length 4
print(x)
print(x.shape)
print(y)
print(y.shape)
[ 0. 2.5 5. 7.5 10. ]
(5,)
[ 0. 0.33333333 0.66666667 1. ]
(4,)
We want to calculate a value for a third vector z
** at every point these two meet**, therefore, we need to express z
with dimensions (len(x), len(y)).
This is where meshgrid()
comes in.
xx, yy = np.meshgrid(x, y)
It produces a matrix xx
where our original vector x
is broadcast as each row, with the same number of rows as y
has length.
print(xx)
print(xx.shape)
[[ 0. 2.5 5. 7.5 10. ]
[ 0. 2.5 5. 7.5 10. ]
[ 0. 2.5 5. 7.5 10. ]
[ 0. 2.5 5. 7.5 10. ]]
(4, 5)
Similarly, yy
has each column as y
vectors, with as many columns as there are x
values.
print(yy)
print(yy.shape)
[[ 0. 0. 0. 0. 0. ]
[ 0.33333333 0.33333333 0.33333333 0.33333333 0.33333333]
[ 0.66666667 0.66666667 0.66666667 0.66666667 0.66666667]
[ 1. 1. 1. 1. 1. ]]
(4, 5)
Now because we have two matricies of the same dimensions, we can do element-wise calculations and preserve our dimensions.
z = xx + yy
z.shape
(4, 5)
z = xx ** yy
z.shape
(4, 5)
z = xx > yy
z.shape
(4, 5)
Contour
Now that we know how to get clean values for Z, generating a contour plot is a simple call to plt.contour()
X = np.linspace(0, 1, 1000)
Y = np.linspace(0, 1, 1000)
xx, yy = np.meshgrid(X, Y)
Z = xx ** 2 - yy
Ez pz
plt.contour(X, Y, Z)
<matplotlib.contour.QuadContourSet at 0x1f8bf254eb8>
Labelling Lines
Labelling the contours is also pretty simple. You may have noticed that the call to contour()
returned a matplotlib.contour.QuadContourSet
object. If we catch this, we can pass it as an argument to ax.clabel()
fig, ax = plt.subplots()
cs = ax.contour(X, Y, Z)
ax.clabel(cs)
# adjusting axis because my X, Y were
# pooly-chosen, lol
ax.set_xlim(0, 1.2)
ax.set_ylim(0, 1.2)
(0, 1.2)
Filled Contour
Filling in the contours is just as simple– merely tacking an f
onto the function name!
plt.contourf(X, Y, Z)
<matplotlib.contour.QuadContourSet at 0x1f8bf5f36d8>