Generate Contour Plots Using Python’s Matplotlib | by Rashida Nasrin Sucky | Towards Data Science

I am sure you have seen a contour plot before. At least in weather data. It is used a lot in presenting meteorological or geographical data. But it is also used to present density, brightness, and electric potential. It is used a lot in data analysis and machine learning. It shows how a response variable relates to two predictor variables.
It gives a two-dimensional view where all the points having the same response are connected by a line. That line is a contour line.
Three main elements of a contour plot:
x-axis and the y-axis shows the predictorsContour lines to represent the same response valuesColored bands that provide a range of response values
x-axis and the y-axis shows the predictors
Contour lines to represent the same response values
Colored bands that provide a range of response values
First import the necessary packages.
import numpy as npimport matplotlib.pyplot as pltimport pylab
Let’s generate some x and y values
xp = np.arange(-8, 10, 2)yp = np.arange(-8, 10, 2)
You can probably imagine how ‘xp’ and ‘yp’ look like. But still, just have a look.
xp
Output:
array([-8, -6, -4, -2,  0,  2,  4,  6,  8])
Input:
yp
Output:
array([-8, -6, -4, -2,  0,  2,  4,  6,  8])
The length of x and y is 9.
This information is important because we need to generate z using this number.
First, initiate a random z point of the shape 9 x 9
zp = np.ndarray((9,9))zp
Output:
array([[1.20117830e-311, 1.20117830e-311, 1.20120150e-311,        1.20120150e-311, 1.20120150e-311, 1.20120150e-311,        1.20118338e-311, 1.20119781e-311, 1.20120151e-311],       [1.20120150e-311, 1.20120151e-311, 1.20117830e-311,        1.20117830e-311, 1.20118045e-311, 1.20120150e-311,        1.20119863e-311, 1.20119863e-311, 1.20117830e-311],       [1.20119864e-311, 1.20118316e-311, 1.20117850e-311,        1.20117830e-311, 1.20118500e-311, 1.20118500e-311,        1.20118490e-311, 1.20118488e-311, 1.20118316e-311],       [1.20118500e-311, 1.20118493e-311, 1.20118493e-311,        1.20118493e-311, 1.20118493e-311, 1.20118339e-311,        1.20117862e-311, 1.20117835e-311, 1.20118337e-311],       [1.20118339e-311, 1.20118338e-311, 1.20118347e-311,        1.20118348e-311, 1.20118339e-311, 1.20118348e-311,        1.20118316e-311, 1.20118338e-311, 1.20118348e-311],       [1.20118339e-311, 1.20118348e-311, 1.20118347e-311,        1.20118348e-311, 1.20118348e-311, 1.20118348e-311,        1.20118339e-311, 1.20118339e-311, 1.20118333e-311],       [1.20118348e-311, 1.20118348e-311, 1.20118348e-311,        1.20117830e-311, 1.20117830e-311, 1.20117853e-311,        1.20117830e-311, 1.20117830e-311, 1.20117830e-311],       [1.20117830e-311, 1.20117830e-311, 1.20117830e-311,        1.20117830e-311, 1.20117830e-311, 1.20117830e-311,        1.20117830e-311, 1.20117830e-311, 1.20117830e-311],       [1.20117830e-311, 1.20117830e-311, 1.20117830e-311,        1.20117830e-311, 1.20117830e-311, 1.20117830e-311,        1.20117830e-311, 1.20117830e-311, 0.00000000e+000]])
Now, I will replace these random values with a formula of my choice. you can use the formula you want or you need.
for x in range(0, len(xp)):    for y in range(0, len(yp)):        zp[x][y] = xp[x]**2 + yp[y]**2zp
Output:
array([[128., 100.,  80.,  68.,  64.,  68.,  80., 100., 128.],       [100.,  72.,  52.,  40.,  36.,  40.,  52.,  72., 100.],       [ 80.,  52.,  32.,  20.,  16.,  20.,  32.,  52.,  80.],       [ 68.,  40.,  20.,   8.,   4.,   8.,  20.,  40.,  68.],       [ 64.,  36.,  16.,   4.,   0.,   4.,  16.,  36.,  64.],       [ 68.,  40.,  20.,   8.,   4.,   8.,  20.,  40.,  68.],       [ 80.,  52.,  32.,  20.,  16.,  20.,  32.,  52.,  80.],       [100.,  72.,  52.,  40.,  36.,  40.,  52.,  72., 100.],       [128., 100.,  80.,  68.,  64.,  68.,  80., 100., 128.]])
So, we have x, y, and z data ready. Here is how to do the contour plot.
plt.figure(figsize=(7, 5))plt.title('Contour Plot')contours = plt.contour(xp, yp, zp)plt.clabel(contours, inline=1, fontsize=12)plt.show()
I will do the exact same procedure with a slightly different formula for z values. So I will not explain step by step this time:
xp = np.arange(-3, 4)yp = np.arange(-3, 4)zp  =np.ndarray((7,7))for x in range(0, len(xp)):    for y in range(0, len(yp)):        zp[x][y] = xp[x]*xp[x] - yp[y]*yp[y]plt.figure(figsize=(8, 6))plt.title('Contour plot for saddle surface - Hyperbolic paraboloid')contours = plt.contour(xp, yp, zp)plt.clabel(contours, inline=1, fontsize=12)plt.show()
This is a density plot. So I will make a different dataset where data points are closer. Here are x and y.
x = np.linspace(0, 5, 60)y = np.linspace(0, 5, 48)
Both x and y are the same. This is how the data look like:
array([0.        , 0.08474576, 0.16949153, 0.25423729, 0.33898305,       0.42372881, 0.50847458, 0.59322034, 0.6779661 , 0.76271186,       0.84745763, 0.93220339, 1.01694915, 1.10169492, 1.18644068,       1.27118644, 1.3559322 , 1.44067797, 1.52542373, 1.61016949,       1.69491525, 1.77966102, 1.86440678, 1.94915254, 2.03389831,       2.11864407, 2.20338983, 2.28813559, 2.37288136, 2.45762712,       2.54237288, 2.62711864, 2.71186441, 2.79661017, 2.88135593,       2.96610169, 3.05084746, 3.13559322, 3.22033898, 3.30508475,       3.38983051, 3.47457627, 3.55932203, 3.6440678 , 3.72881356,       3.81355932, 3.89830508, 3.98305085, 4.06779661, 4.15254237,       4.23728814, 4.3220339 , 4.40677966, 4.49152542, 4.57627119,       4.66101695, 4.74576271, 4.83050847, 4.91525424, 5.        ])
As before I need a function for z. Here is the function I choose,
def fn(x, y):    return np.sin(x)**5 + np.cos(y+17)**8
Now, time to prepare the X, Y, and Z data. I will simply use the np.meshgrid function on x and y which builds two-dimensional grids from one-dimensional arrays.
X, Y = np.meshgrid(x, y)Z = fn(X, Y)
The data is ready. Here is the simplest, black and white density contour plot.
plt.contour(X, Y, Z, colors = 'black')
Let’s add a colormap also specify that we want 15 equally spaced lines drawn within the range.
plt.figure(figsize=(8, 6))contours = plt.contour(X, Y, Z, 15, cmap = 'RdGy')plt.clabel(contours, inline=True, fontsize=12)
There is another function in matplotlib that is contourf. Now, see an example of contourf.
plt.figure(figsize=(14, 10))plt.contourf(X, Y, Z, 20, cmap = 'RdGy')plt.colorbar()
plt.figure(figsize=(14, 10))plt.imshow(Z, extent=[0,6,0,6], origin='upper', cmap='RdGy')plt.colorbar()
We can even place that black and white contour plot on top of this imshow.
plt.figure(figsize=(14, 10))contours = plt.contour(X, Y, Z, 15, colors='black')plt.clabel(contours, inline=True, fontsize=12)plt.imshow(Z, extent=[0,6,0,6], origin='upper', cmap='RdGy', alpha=0.5)plt.colorbar()
I like it! How about you?
If you never made a contour plot before, I hope you will now whenever necessary. It gives a lot of information and also looks nice! If you are a machine learning modeler, use a contour plot to visualize the range in different classes or anomaly in the data.
Feel free to follow me on Twitter and like my Facebook page.