2023-01-23
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.
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.
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.
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.
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.
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.
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')
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 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)\).
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.
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.
In this lesson, we have seen how matplotlib is used to produce
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.