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.
Say we’ve got two simple vectors,
%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
y has length
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.
[[ 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)
yy has each column as
y vectors, with as many columns as there are
[[ 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
z = xx ** yy z.shape
z = xx > yy z.shape
Now that we know how to get clean values for Z, generating a contour plot is a simple call to
X = np.linspace(0, 1, 1000) Y = np.linspace(0, 1, 1000) xx, yy = np.meshgrid(X, Y) Z = xx ** 2 - yy
plt.contour(X, Y, Z)
<matplotlib.contour.QuadContourSet at 0x1f8bf254eb8>
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
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)
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>