We’ve already generated quite a few figures in these lectures using Matplotlib

Matplotlib is interesting in that it provides two fairly different interfaces

The first is designed to mimic MATLAB graphics functionality, and is aimed mainly at beginners

The second is object oriented, more Pythonic and more powerful, but requires some more effort to learn

In this lecture we’ll cover both, with a focus on the second method

Matplotlib is very easy to get started with, thanks to its simple MATLAB-style API (Application Progamming Interface)

Here’s an example

```
from pylab import *
x = linspace(0, 10, 200)
y = sin(x)
plot(x, y, 'b-', linewidth=2)
show()
```

The figure it generates looks as follows

(Source code, png, hires.png, pdf)

If you’ve run these commands inside the IPython notebook with the `--pylab inline` flag

- the figure will appear embedded in your browser
- the
`from pylab import *`line is unnecessary

If you’ve run these commands in IPython without the `--pylab inline` flag, it will appear as a separate
window, like so

The buttons at the bottom of the window allow you to manipulate the figure and then save it if you wish

Note that the `pylab` module combines core parts of `matplotlib`, `numpy` and `scipy`

Hence `from pylab import *` pulls NumPy functions like `linspace` and `sin` into the global namespace

Most people start working with Matplotlib using this MATLAB style

The MATLAB style API is simple and convenient, but it’s also a bit limited and somewhat un-Pythonic

For example, in the code above, we use `from pylab import *`

Here we are pulling lots and lots of names into the global namespace, which is *not really a good idea*

In particular, with `import *` we’re pulling in a lot of names and we don’t even know what we’re pulling in

To a trained Python programmer this is a horrible idea

It’s better to be explicit rather than implicit (type `import this` in the IPython (or Python) shell and look at the second line)

This leads us to the alternative, object oriented API

Here’s the code corresponding to the preceding figure using this second approach

```
import matplotlib.pyplot as plt
import numpy as np
fig, ax = plt.subplots()
x = np.linspace(0, 10, 200)
y = np.sin(x)
ax.plot(x, y, 'b-', linewidth=2)
plt.show()
```

While there’s a bit more typing, the more explicit declarations will give us far more fine-grained control

This will become more clear as we go along

Incidentally, regarding the above lines of code,

the form of the import statement

`import matplotlib.pyplot as plt`is standardHere the call

`fig, ax = plt.subplots()`returns a pair, where`fig`is a`Figure`instance—like a blank canvas`ax`is an`AxesSubplot`instance—think of a frame for plotting in

The

`plot()`function is actually a method of`ax`

Here we’ve changed the line to red and added a legend

```
import matplotlib.pyplot as plt
import numpy as np
fig, ax = plt.subplots()
x = np.linspace(0, 10, 200)
y = np.sin(x)
ax.plot(x, y, 'r-', linewidth=2, label='sine function', alpha=0.6)
ax.legend()
plt.show()
```

(Source code, png, hires.png, pdf)

We’ve also used `alpha` to make the line slightly transparent—which makes it look smoother

Unfortunately the legend is obscuring the line

This can be fixed by replacing `ax.legend()` with `ax.legend(loc='upper center')`

(Source code, png, hires.png, pdf)

If everthing is properly configured, then adding LaTeX is trivial

```
import matplotlib.pyplot as plt
import numpy as np
fig, ax = plt.subplots()
x = np.linspace(0, 10, 200)
y = np.sin(x)
ax.plot(x, y, 'r-', linewidth=2, label=r'$y=\sin(x)$', alpha=0.6)
ax.legend(loc='upper center')
plt.show()
```

The `r` in front of the label string tells Python that this is a raw string

The figure now looks as follows

(Source code, png, hires.png, pdf)

Controlling the ticks, adding titles and so on is also straightforward

```
import matplotlib.pyplot as plt
import numpy as np
fig, ax = plt.subplots()
x = np.linspace(0, 10, 200)
y = np.sin(x)
ax.plot(x, y, 'r-', linewidth=2, label=r'$y=\sin(x)$', alpha=0.6)
ax.legend(loc='upper center')
ax.set_yticks([-1, 0, 1])
ax.set_title('Test plot')
plt.show()
```

Here’s the figure

(Source code, png, hires.png, pdf)

It’s straightforward to generate mutiple plots on the same axes

Here’s an example that randomly generates three normal densities and adds a label with their mean

```
import matplotlib.pyplot as plt
import numpy as np
from scipy.stats import norm
from random import uniform
fig, ax = plt.subplots()
x = np.linspace(-4, 4, 150)
for i in range(3):
m, s = uniform(-1, 1), uniform(1, 2)
y = norm.pdf(x, loc=m, scale=s)
current_label = r'$\mu = {0:.2f}$'.format(m)
ax.plot(x, y, linewidth=2, alpha=0.6, label=current_label)
ax.legend()
plt.show()
```

(Source code, png, hires.png, pdf)

At other times we want multiple subplots in one figure

Here’s an example that generates 6 histograms

```
import matplotlib.pyplot as plt
import numpy as np
from scipy.stats import norm
from random import uniform
num_rows, num_cols = 3, 2
fig, axes = plt.subplots(num_rows, num_cols, figsize=(8, 12))
for i in range(num_rows):
for j in range(num_cols):
m, s = uniform(-1, 1), uniform(1, 2)
x = norm.rvs(loc=m, scale=s, size=100)
axes[i, j].hist(x, alpha=0.6, bins=20)
t = r'$\mu = {0:.1f}, \quad \sigma = {1:.1f}$'.format(m, s)
axes[i, j].set_title(t)
axes[i, j].set_xticks([-4, 0, 4])
axes[i, j].set_yticks([])
plt.show()
```

The output looks as follows

(Source code, png, hires.png, pdf)

In fact the preceding figure was generated by the code above preceded by the following three lines

```
from matplotlib import rc
rc('font',**{'family':'serif','serif':['Palatino']})
rc('text', usetex=True)
```

Depending on your LaTeX installation, this may or may not work for you — try experimenting and see how you go

Perhaps you will find a set of customizations that you regularly use

Suppose we usually prefer our axes to go through the origin, and to have a grid

Here’s a nice example from this blog of how the object-oriented API can be used to build a custom `subplots` function that implements these changes

Read carefully through the code and see if you can follow what’s going on

```
import matplotlib.pyplot as plt
import numpy as np
def subplots():
"Custom subplots with axes throught the origin"
fig, ax = plt.subplots()
# Set the axes through the origin
for spine in ['left', 'bottom']:
ax.spines[spine].set_position('zero')
for spine in ['right', 'top']:
ax.spines[spine].set_color('none')
ax.grid()
return fig, ax
fig, ax = subplots() # Call the local version, not plt.subplots()
x = np.linspace(-2, 10, 200)
y = np.sin(x)
ax.plot(x, y, 'r-', linewidth=2, label='sine function', alpha=0.6)
ax.legend(loc='lower right')
plt.show()
```

Here’s the figure it produces (note axes through the origin and the grid)

(Source code, png, hires.png, pdf)

The custom `subplots` function

- calls the standard
`plt.subplots`function internally to generate the`fig, ax`pair, - makes the desired customizations to
`ax`, and - passes the
`fig, ax`pair back to the calling code

- The Matplotlib gallery provides many examples
- A nice Matplotlib tutorial by Nicolas Rougier, Mike Muller and Gael Varoquaux
- mpltools allows easy switching between plot styles
- Seaborn facilitates common statistics plots in Matplotlib