Contour plots

In this example we show how to make a contour plot with level lines for a circular bowl. The elevation function is

\begin{displaymath}
z = f(x,y) = x^2 + y^2
\end{displaymath} (1)

and we will draw contours over the $x,y$ plane at elevations $z =
1$, 2, and 3. In other words, we draw the circles based on the equations
$\displaystyle x^2 + y^2$ $\textstyle =$ $\displaystyle 1$ (2)
$\displaystyle x^2 + y^2$ $\textstyle =$ $\displaystyle 2$ (3)
$\displaystyle x^2 + y^2$ $\textstyle =$ $\displaystyle 3$ (4)

Pyplot won't work from the definition of the function itself. We have to create a mesh of points in the $x,y$ plane, then evaluate the elevation function at each of these mesh points, and hand Pyplot the mesh and the calculated elevations. Pyplot then uses interpolation to estimate the locations in $x,y$ where the elevations match the desired levels. The quality of the result depends on the resolution of the mesh. If the mesh is too coarse, the interpolation will not give a good approximation to the function and the result will be unfaithful or low quality.

Here is the example code and explanation.

#! /usr/bin/python3                                                              

import numpy as np
import matplotlib.pyplot as plt

delta = 0.2
x = np.arange(-3.0, 3.0, delta)
y = np.arange(-3.0, 3.0, delta)
X, Y = np.meshgrid(x, y)
Z =  X*X + Y*Y
levels = [1,2,3]
CS = plt.contour(X,Y,Z,levels)
plt.clabel(CS, inline=True, fontsize=10)
plt.show()

The command

x = np.arange(-3.0, 3.0, delta)

creates a numpy vector of $x$ values ranging from $-3$ to $3$, spaced by delta, which is 0.2 here. This spacing controls the coarseness of the mesh. The script defines a similar vector for the $y$ direction. In this case it is the same as $x$, so the duplication isn't necessary. But they don't need to be the same.

X, Y = np.meshgrid(x, y)

Say we have $n_x$ $x$ and $n_y$ $y$ values. This command converts them into $n_x \times n_y$ pairs of values that define the two-dimensional mesh. The pairs of mesh coordinates are split into $X$ and $Y$ vectors, each of length $n_x \times n_y$.

Z =  X*X + Y*Y

This command calculates the elevation of each mesh point.

levels = [1,2,3]

This list defines the desired contour elevations.

CS = plt.contour(X,Y,Z,levels)

This pyplot function creates the countour plot and assigns it to the object CS. The plot does not appear yet.

plt.clabel(CS, inline=True, fontsize=10)

This command specifies that the contour elevations are to be written on the plot lines. It also controls the font size for the labels.

plt.show()

Finally, this command displays the plot.

If you run this example, you may notice that the circles look like ellipses. This happens because the plot frame does not have a 1:1 aspect ratio. There are pyplot commands that control this, but if this bothers you, a simple solution is to square up the plot window by resizing it with your mouse.