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>
