Lesson 10. More on Graphics

2023-01-23

Visualisation of Multidimensional Functions

The plot command suffices for graphing simple curves of the form \(y=f(x)\). For more complex plots handling functions of several variables or vector-valued functions, the Matplotlib module provides additional commands.

Objectives

The aim of this lesson is to describe a range of additional plot types provided by Matplotlib. By the end of this lesson, you will be able to create

We will also see how to save a plot to a graphics file that could, for instance, be included in a document.


Reminder

We mentioned in Lesson 5 that you might need to add the command

plt.show()

after your plotting commands in order for the plot to appear. Also, you should close all plot windows before trying to produce a new plot or an updated version of the current plot. You can either use the mouse or type the command

plt.close()

at the IPython prompt. Doing plt.close('all') closes all the plot windows.


Parametric Plots

In this and the following sections, our examples will assume that the command

from numpy import *
import matplotlib.pyplot as plt

has been executed beforehand so that we can use numpy commands and access plotting commands via plt. Depending on how you run the commands, you might need to use plt.show() to actually display the graphics window.

The basic plot command can be used to plot a parametric curve, as in the following example where we plot an ellipse.

t = linspace(-pi, pi, 301)
x = 3 * cos(t)
y = sin(t)
plt.plot(x, y)
plt.axis('scaled')
plt.grid(True)
plt.xlabel('x')
plt.ylabel('y')

The output is shown below.

Parametric Plot of an Ellipse

Logarithmic Scales

If the y-values of a plot vary over several orders of magnitude, then a log scale on the y-axis will often allow the behaviour of the curve to be seen more clearly. The semilogy function provides exactly this functionality.

x = linspace(0, 200, 301)
y1 = 1 / ( 1 + x )**2
y2 = 1 / ( 1 + x )**4
plt.subplot(2, 1, 1)
plt.plot(x, y1, x, y2)
plt.grid(True)
plt.legend(('y=1/(1+x)^2', 'y=1/(1+x)^3'))
plt.subplot(2, 1, 2)
plt.semilogy(x, y1, x, y2)
plt.grid(True)
plt.xlabel('x')
plt.legend(('y=1/(1+x)^2', 'y=1/(1+x)^3'))

The output is shown below.

Comparing plot (top) with semilogy (bottom)

The semilogx command is similar, but uses a log scale on the x-axis (with a linear scale on the y-axis). There is also loglog that uses a log scale on both the x- and y-axes.


Contour Plots

Recall that a contour or level set of a real-valued function \(f(x,y)\) is a curve of the form \(f(x, y)=c\) for some constant \(c\). A standard way to visualise a such a function \(f\) is to plot the family of contours determined by a sequence of values for the constant \(c\).

The following commands create a contour plot for the function \(f(x, y)=x^3-3x+y^2\).

def f(x, y):
    return x**3 - 3*x + y**2

x = linspace(-3, 3, 250)
y = linspace(-4, 4, 200)
X, Y = meshgrid(x, y)
Z = f(X, Y)
c = arange(-20, 31, 2)
plt.contour(X, Y, Z, c)
plt.colorbar()
plt.xlabel('x')
plt.ylabel('y')
plt.grid(True)
plt.show()
plt.savefig('contour_plot.jpg')
A Contour Plot

The NumPy function meshgrid takes two vector arguments, x and y, and returns two matrices X and Y with entries X[i,j] = x[j] and Y[i,j] = y[i]. In this way, the statement Z = f(X, Y) creates a matrix Z with entries Z[i,j] = f(x[j], y[i]). The fourth argument of the contour function determines the constants used to define the family of contours that are plotted. You can omit this argument, in which case a family of contours is chosen automatically, or you can specify the number of contours instead of a vector of constant values. In practice, you often want to start with, say, plt.contour(X, Y, Z, 10) to get 10 contours, and then fine tune the plot with a customised vector c. Note the colorbar command that produces the color bar at the right of the plot.

An alternative version of the contour function, called contourf, produces a ‘filled contour plot’, shown below.

A Filled Contour Plot

Quiver Plots

A quiver plot is used to visualise a 2D vector field, that is, a vector valued function \(f(x, y)=[u(x,y), v(x,y)]^\top\). In the example below, \(u=\sin(y)\) and \(v=-x\).

x = linspace(-1, 1, 15)
y = linspace(-pi, pi, 15)
X, Y = meshgrid(x, y)
U = sin(Y)
V = -X
plt.quiver(X, Y, U, V)

We create matrices X and Y using meshgrid as before, but with only 15 points in each direction. The corresponding matrices U and V hold the values U[i,j] = u(X[i,j], Y[i,j]) and V[i,j] = v(X[i,j], Y[i,j]) of the components of the vector field at the point (X[i,j], Y[i,j]). The quiver command uses all four matrices to plot the vector \([u,v]^\top\) for each grid point \((x,y)\).

A Quiver Plot

Surface Plots

Another way to visualise a real-valued function \(f(x, y)\) is to plot the graph \(z=f(x, y)\) in xyz-space. In the following example, we use the same arrays X, Y and Z as in the contour plot examples above, that is,

x = linspace(-3, 3, 250)
y = linspace(-4, 4, 200)
X, Y = meshgrid(x, y)
Z = f(X, Y)

Producing 3D graphics with Matplotlib requires a more object-based style of programming than is necessary for 2D plotting.

fig = plt.figure(1)
ax = fig.add_subplot(projection='3d')
ax.view_init(elev=23, azim=-123)
surf = ax.plot_surface(X, Y, Z, cmap='coolwarm')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
fig.colorbar(surf, shrink=0.5)

We first create a figure object fig, and add a 3D axis object ax as a subplot of the figure. The view angle is adjusted from its default, and then the plot_surface method creates the surface object from the x-, y- and z-values provided by the three arrays. The ‘coolwarm’ color map is chosen to associate a color with each z-value. We label the axes and finally add a colorbar.

A Surface Plot

Saving a Plot to an Image File

Once you have created a Matplotlib graphics figure, you can save it to an image file using the plt.savefig function. For example,

plt.savefig('myplot.jpg')

saves the plot in JPEG format to a file called myplot.jpg. The image file format is inferred from the file extensions; other supported formats are .pdf, png and .eps.


Summary

In this lesson, we have seen how matplotlib is used to produce

Further Reading

The matplotlib documentation includes a large number of Examples. This is often the best place to start if you do not know how to go about creating a particular kind of plot.

Back to All Lessons