# Plotting¶

In addition to the **very** efficient numerical computation that is possible with the NumPy array, another majoring selling point of the Python language for scientific applications is the ability to produce high-quality plots and graphs easily.
This is due to the package known as `matplotlib`

, pronounced *mat-plot-lib*.

`matplotlib`

is particularly useful in combination with the NumPy arrays introduced previously.
Let’s see an example,

```
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-5, 5, 9)
print("Values in the array:", x)
plt.plot(x, x ** 2)
plt.show()
```

```
Values in the array: [-5. -3.75 -2.5 -1.25 0. 1.25 2.5 3.75 5. ]
```

In the cell above we do the following:

Import the

`numpy`

package and store it with the shortcut`np`

.Import the

`pyplot`

library from the`matplotlib`

package, with the shortcut`plt`

(`plt`

is the standard shortcut).Generate an array containing nine values, linearly-spaced from -5 to 5. These values are then printed.

Draw a plot with the array

`x`

on the*x*-axis and the square of this array on the*y*-axis.Show the plot. This final function returns

`None`

(similar to`print()`

) but shows the plot in the notebook.

The popularity of `matplotlib`

is driven heavily by the broad capability of the package.
We will look quickly at some customisation that is possible:

Adding axis titles.

Changing the plot type (line, scatter, etc.).

Using logarithmic axes.

Plotting data with error bars. As in much of the Python programming language, if you want to do something with

`matplotlib`

there is probably a stackoverflow question about it, so feel free to play about and learn other functionality.

Let’s consider plotting the concentration of ^{19}F as it decays to ^{18}O, following a first-order rate law, the data for which is in the table below.

Time/s |
Concentration/M |
---|---|

0 |
9.97±0.50 |

60 |
9.91±0.50 |

360 |
9.60±0.48 |

600 |
9.36±0.47 |

3600 |
6.83±0.34 |

14400 |
2.19±0.11 |

We will store each of these datasets (the time, the concentration, and the uncertainty in the concentration) as individual NumPy arrays.

```
time = np.array([0, 60, 360, 600, 3600, 14400])
conc = np.array([9.97, 9.91, 9.60, 9.36, 6.83, 2.19])
u_conc = np.array([0.50, 0.50, 0.48, 0.47, 0.34, 0.11])
```

We can now plot the *x* and *y* data without error bars, using a similar command to the one above.

```
plt.plot(time, conc, 'o')
plt.xlabel('Time/s')
plt.ylabel('Concentration/M')
plt.show()
```

Note, that the `'o'`

in the `plt.plot()`

function resulted in a scatter plot, with no line joining the points.
Additionally, strings given to the `plt.xlabel()`

and `plt.ylabel()`

commands are added as axis labels.

We can also produce a `matplotlib`

plot that shows the uncertainty measurements as error bars and scales the axis to make things a bit clearer.

```
plt.errorbar(time, conc, u_conc, marker='o')
plt.xlabel('Time/s')
plt.ylabel('Concentration/M')
plt.yscale('log')
plt.show()
```

Above, the `plt.errorbar()`

function is used instead of the `plt.plot()`

function, be aware that the `'o'`

argument will only work for this function if preceded by `marker=`

.
Additionally, we can produce a logarithmic *y*-axis (particularly useful for this example with a first-order rate law) using the `plt.yscale()`

command (a similar `plt.xscale()`

command also exists.