Lesson 5. Plotting

2023-01-23

Visualisation

Many applications of computational mathematics involve processing large arrays of data, and often the best way to make sense of such a volume of numerical output is with some appropriate kind of visualisation. For this reason, the ability to turn numbers into pictures has always played an essential role in scientific computing.

Objectives

This lesson will focus on creating simple two-dimensional plotting using a Python package called matplotlib, which derives its name from the fact that its commands are similar to those used in Matlab. By the end of the lesson, you should know how to


The plot Command

Start the Spyder IDE and type the following commands in the IPython shell.

x = linspace(0, 2*pi, 401)
y = sin(x)
plot(x, y)

In the top right pane, select the ‘Plots’ tab and you should see something similar to the screenshot below

Plotting in Spyder

Here, we used the linspace function to create an array x of \(401\) linearly spaced points from \(0\) to \(2\pi\), and then took advantage of the fact that the NumPy function sin is a ufunc or universal function, meaning that if its argument is a NumPy array then sin returns an array whose kth entry is the value of the sine function at the kth entry of its argument. Thus, in our case y will be an array of 401 numbers with y[k]=sin(x[k]) for \(0\le k\le400\).

The plot command simply draws straight line segments between consecutive points (x[k], y[k]). By choosing sufficiently many points, the resulting polygonal arc looks like a smooth curve.

Exercise. Plot \(y=\sin(x)\) again, but this time use only \(11\) points instead of \(401\) points.

You can modify the plot style using an optional format string. For example,

plot(x, y, '--')

will produced a dashed line, whereas ':' produces a dotted line and '-.' produces a dash-dot line. To override the default colour choice you can include a letter code as the start of the format string. For example,

plot(x, y, 'r:')

will produce a red dotted line. The table below lists the available colour options.

letter colour
b blue
g green
r red
m magenta
y yellow
k black

As well as plotting curves, you can also plot discrete data using a variety of different symbols. Try the following example.

x = linspace(1, 5, 9)
y = exp(-x/2) + 0.2 * sin(40*x)
plot(x, y, 'go')

In the format string 'go', the first character g is the colour code for ‘green’, and the second character o tells matplotlib to plot each point as a circular dot. The table below lists some of the possible symbols; the complete list is given in the docstring for plot.

character description
. point
o circular dot
v triangle down
^ triangle up
< triangle left
> triangle right
s square
+ plus
x x

Simple Plot Annotations

When creating more elaborate plots with Python you will usually want to type the commands into a .py file rather than at the IPython prompt.
Also, a limitation of the plot window in Spyder is that each plot command creates a new plot, so you cannot build up a plot over several steps.

From the ‘Tools’ menu, select ‘Preferences’ and then, in the left pane of the Preferences window, select ‘IPython console’. Click on the ‘Graphics’ tab in the right pane and under ‘Graphics backend’ select ‘Automatic’ from the drop-down menu so that plots will appear in a stand-alone window. In the dialogue box that appears, check the box ‘Apply to current console and restart kernel’ and then click ‘Keep Existing Kernels’.

Type the following lines in the Spyder edit window and save to a file sine_plot.py.

import matplotlib.pyplot as plt
from numpy import linspace, pi, sin

x = linspace(0, 2*pi, 401)
y = sin(x)

plt.plot(x, y)
plt.xlabel('x')
plt.ylabel('y')
plt.grid(True)
plt.title('The Graph of y = sin(x)')

After running the code, you should see the picture below; if not, edit the file by adding the command

plt.show()

at the end. The commands are all pretty self-explanatory: xlabel and ylabel produce axis labels, grid displays a background grid, and title adds a title at the top of the plot.

Plot with axis labels, title and grid

Since we are no longer running the commands directly in the IPython shell, we have to import the plotting commands from the pyplot submodule of matplotlib. The use of plt as an abbreviation for use in qualified function names is standard. The command

plt.close()

closes the current plot window. It is a good idea to close the plot window before trying to update the plot or create a new one.


Multiple Plots

We can plot multiple curves using a single plot command. Save a second copy of your sine_plot.py file as sine_cosine_plot.py, and edit the new file, importing cos from NumPy and replacing the line y = sin(x) with

y1 = sin(x)
y2 = cos(x)

You can then replace the call to plot by

plt.plot(x, y1, x, y2)
plt.legend(('$y=\sin(x)$', '$y=\cos(x)$'))

and change the title to ‘Trigonometric Functions’. Running sine_cosine_plot.py should produce the plot figure shown below. Notice that plot automatically draws the curves in different colors, and does a good job of placing the legend in a location that does not obscure the curves. When using a single plot command to plot multiple curves, you can include a format string after any pair of x and y vectors.

Plotting two curves on the same axes

Subplots

Download and run the file subplots_example.py, which draws four subplots in a \(2\times2\) grid layout. Before each plot command is a command of the form

plt.subplot(2, 2, k)

for an index k running from 1 to 4. In general, we can create an \(m\times n\) grid of subplots, indexed from \(1\) to \(mn\) in row-major order: starting with \(1\) in the top-left and proceeding from left to right and then from top to bottom. In practice, the most common layouts are \(2\times1\), \(1\times2\) and \(2\times2\); the subplots will generally be too small if you try to fit more in.

Axis Tweaks

The plot command does a good job of automatically choosing appropriate ranges on the x- and y-axes, but you can use the axis command to force a different choice. If you have created a plot, then the command

xmin, xmax, ymin, ymax = plt.axis()

returns the current minimum and maximum values for x and y. You can change all four values by doing

plt.axis([new_xmin, new_xmax, new_ymin, new_ymax])

Note that we provide axis with a single argument consisting of a list of four numbers. You can use the command

plt.xlim([new_xmin, new_xmax])

if you want to change only the x limits, and

plt.ylim([new_ylim, new_xlim])

for changing only the y limits. If you are typing these commands in the IPython shell then you can leave off the plt. qualifier and just type axis etc.

Another form of the axis function has a single string as its argument, with the result set out in the following table. Notice in particular that you should use axis('equal') or axis('scaled') if you want a circle to look like a circle rather than an ellipse.

Argument Result
‘off’ Turn off axis lines and labels
‘equal’ Use equal scales on x- and y-axes
‘scaled’ Resize the plot box to achieve equal x- and y-scales

Exercise. Look at the docstrings for xticks and yticks to learn how you can customise the tick marks and labels along x- and y-axes.

Polar Plots and Histograms

The polar function is used for plotting curves given in polar coordinates. For example, try plotting \(r=1+\cos(\theta)\) for \(-\pi\le\theta\le\pi\) as follows (from the IPython prompt).

theta = linspace(-pi, pi, 201)
r = 1 + cos(theta)
polar(theta, r)

When dealing with statistical data, we often want to plot a histogram to visualise the distribution of a random quantity. In the following code block, the function randn returns a vector of 500 samples from the standard normal distribution, after which hist displays a histogram with 20 bins.

x = randn(500)
hist(x, 20)

Multiple Figure Windows

Sometimes you want to create several plots at once, each in its own figure window. Ensure that the graphics backend is set to ‘Automatic’ as explained above.

The command figure(k) creates a figure window and directs subsequent graphics commands there, so you can call figure(1) and create your first plot, then figure(2) with your second plot, and so on. The command close(k) will close the kth window, and close('all') will close all windows.


Summary

In this lesson, we saw how to

Further Reading

The official matplotlib documentation includes the Pyplot tutorial which covers some of the same topics as this lesson.

Back to All Lessons