`matplotlib`

The python module `matplotlib`

is a very widely used package. It is based on the plotting in the commercial program `Matlab`

. There are several way to import and use `matplotlib`

. We will use what is called the *object-oriented* approach. You can see in the cell below how the module is imported in this approach.

The line `%matplotlib inline`

tells jupyter to display the plots in this web browser page.

Run the cell below to read in the `numpy`

and `matplotlib`

modules and set up the inline plots.

To get you started I put in some code to create some data.

```
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
#
# Now make some data
np.random.seed(20150108) # seed the random number generator so eveyone has the same data
time = np.linspace(0, 2, 101)
volts = 2.5 * np.sin(2 * np.pi * time + 1.0) + np.random.normal(0,0.1,len(time))
vModel = 2.5 * np.sin(2 * np.pi * time + 1.0)
```

1

In [3]:

%matplotlib inline import numpy as np import matplotlib.pyplot as plt # # Now make some data np.random.seed(20150108) # seed the random number generator so eveyone has the same data time = np.linspace(0, 2, 101) volts = 2.5 * np.sin(2 * np.pi * time + 1.0) + np.random.normal(0,0.1,len(time)) vModel = 2.5 * np.sin(2 * np.pi * time + 1.0)

2

I hesitate even showing you how to do this, but *quick and dirty* plots can be made with the one line of code:

```
plt.plot(time, volts)
```

Go ahead and run this in the cell below.

3

In [2]:

plt.plot(time, volts)

4

[<matplotlib.lines.Line2D at 0x7f5e9f112a30>]

To make a minimally satisfactory plot, you need axis labels, and to change the plot from a line to points. These and many other plot features are easier to do with an *object oriented* approach. Object oriented means you create an object, then call that object's methods to modify it.

First you need a * figure*. A figure is the canvas or space onto which the plot is drawn. The basic call to create a figure is

```
fig = plt.figure()
```

Run by itself, you will not see anything happen.

Second, you need * axes* in the figure. The easiest way to do this is running

```
ax = fig.add_subplot(111)
```

You can see that `fig`

has a method `add_subplot`

. `sub_plot`

can configure multiple plots in one figure. The odd argument `111`

means one row of figures, one column of figures, and these are the axes for the first figure.

Finally, you need your plot. This takes the form

```
pl1 = ax.plot(time, volts)
```

Note that each time you create an object, you save a reference to it by the `=`

operator.

5

In [4]:

fig = plt.figure() ax = fig.add_subplot(111) pl1 = ax.plot(time, volts)

6

It is in embellishing the plot that the object-oriented approach helps. Every plot needs two things: a title, and axis labels. These are added with methods on the axis object.

```
ax.set_xlabel("myXLabel")
```

sets `"myXLabel"`

as the x label. Your label should have a one or two word description followed by the units in parentheses, like `Time (s)`

. Similarly, the method for adding a y label is

```
ax.set_ylabel(FILL THIS IN)
```

To add a title, the method is

```
ax.set_title(GIVE ME A TITLE)
```

Give the plot the title `Sensor Output`

.

Unfortunately, jupyter can't modify the plot in a previous cell. So, in the cell below, copy and paste the code, then add the code for adding the labels and title.

7

In [6]:

fig = plt.figure() ax = fig.add_subplot(111) pl1 = ax.plot(time, volts) ax.set_xlabel("myXLabel") ax.set_ylabel("Time (s)") ax.set_title("Fun Plot")

8

Text(0.5, 1.0, 'Fun Plot')

One problem with the above plot is that since the data is not smooth, it should be plotted with dots or symbols. Data should almost always be plotted with dots or symbols. `matplotlib`

, like `Matlab`

, dies this with a formatting parameterin the `plot`

command. You can append and optional third parameter after the y array with formatting information about the plot line. This formatting is a very compact string with the line type, the symbol, and the color encoded in a three character string. Here are some examples:

`'-k'`

- plots only a black line. (`k`

means blac.)**k**`'.r'`

- plots only dots in the color red`'--g'`

- plots only a green dashed line`'ob'`

- plots only circles in blue`'^:m'`

- plots triangle connected by a dotted line in magenta`help(plt.plot)`

is always available with more options and details

Other colors are `y`

and `c`

. Other symbols are `v`

, `*`

, `+`

, `x`

, `'s'`

, and `d`

. Another line types is `'-.'`

. Your plot should have a line like

```
ax.plot(time, volts, '.b')
```

and another line to plot model as a solid red line.

Adding another line (or set of symbols) to the plot is just a matter of adding another `ax.plot`

call. Each sucessive call of `plot`

will add another line to the axis.

Copy and paste your previous code in the cell below. Then modify it to plot the data points in blue dots without a line, and the model `vModel`

as a red smooth line.

If yours does not, keep trying until it does.

9

In [8]:

fig = plt.figure() ax = fig.add_subplot(111) pl1 = ax.plot(time, volts) ax.set_xlabel("myXLabel") ax.set_ylabel("Time (s)") ax.set_title("Fun Plot") ax.plot(time, volts, '.b')

10

[<matplotlib.lines.Line2D at 0x7f5e9cf88fa0>]

The next two modifications are optional. Often it is useful to have background grid on your plots. This is done by calling `ax.grid()`

.

Next, sometimes you are plotting multiple data sets or models on the graph, so you need a *legend* to help the reader decode what you plotted. There are two steps to doing this.

- In each call to
`plot`

, add a parameter like`label="Data"`

. Whatever string you assign to`label`

will be used in making a legend. - Add a call

```
ax.legend()
```

after your last call to `plot`

. This turns on the legend.

In the cell below, add a grid and legend to your plot.

11

In [12]:

fig = plt.figure() ax = fig.add_subplot(111) pl1 = ax.plot(time, volts) ax.set_xlabel("Volts (v)") ax.set_ylabel("Time (s)") ax.set_title("Fun Plot") ax.plot(time, volts, '.b') label = "DM" ax.legend(label)

12

<matplotlib.legend.Legend at 0x7f5e9cc370a0>

Usually `matplotlib`

chooses the axis limits well, but sometimes the default limits need to be adjusted. The methods

```
ax.set_xlim(min,max)
ax.set_ylim(min,max)
```

set the limits to your choice. For example setting the y limits from -2.8 to 3.8 leaves better room for the legend box.

Copy and paste your previous code and add both x and y limits to the plot. Also expanding the x limits a little bit, like 0.1 could show better where the data begins and ends.

It should look like the figure above.

13

In [13]:

fig = plt.figure() ax = fig.add_subplot(111) pl1 = ax.plot(time, volts) ax.set_xlabel("Volts (v)") ax.set_ylabel("Time (s)") ax.set_title("Fun Plot") ax.plot(time, volts, '.b') label = "DM" ax.legend(label) ax.set_xlim(0,2) ax.set_ylim(-2.8, 3.8)

14

(-2.8, 3.8)

Sometimes your data or models are shown better with a logarithmic axis for one or both axes. The methods

```
ax.set_yscale('log')
ax.set_xscale('log')
```

change the scaling on the respective axes.

Use the following code in the cell below to generate more data

```
volts2 = 3 * np.exp(-time/0.25)
```

Then plot it using a logarithmic y-axis.

15

In [10]:

fig = plt.figure() volts2 = 3 * np.exp(-time/0.25) ax = fig.add_subplot(111) pl1 = ax.plot(time, volts2) ax.set_xlabel("Volts (v)") ax.set_ylabel("Time (s)") ax.set_title("Fun Plot") ax.plot(time, volts, '.b') label = "DM" ax.legend(label) ax.set_xlim(0,2) ax.set_ylim(-2.8, 3.8) ax.set_yscale('log') ax.set_xscale('log')

16

Now to demonstrate the log-log plot, create the following data:

```
time3 = time[1:]
volts3 = time3 ** -2
```

We want to plot this data in plot linear and log-log axis scaling. The example below does some fancy figure handling.

- I set the
`figsize`

manually to be extra wide by using

```
fig = plt.figure(figsize=(12,5))
```

- I add a subplot axis using
`121`

. This means there will be one*row*amd two*columns*of plots, and this plot will be the first. - The next set of axes are the second one, so it will be in the second columns. Note the first two numbers have to match.
- I set the scales only on the second axis.
- I use a
`for`

loop to loop over both sets of axes. It turns out that the variable`fig.axes`

is a list of all of the axes in the current figure. - In the loop I set the labels and turn on the grids. Here is part of the code to do this

```
for ax in fig.axes:
ax.set_title("Amplifier Output")
SET THE X LABEL
SET THE Y LABEL
TURN ON THE GRID
```

Keep trying until it looks like the above plots.

17

In [4]:

18

In [6]:

19

<Figure size 864x360 with 0 Axes>

<Figure size 432x288 with 0 Axes>

In [11]:

fig = plt.figure() ax = fig.add_subplot(111) fig = plt.figure(figsize=(12,5)) pl1 = ax.plot(time3, volts3) time3 = time[1:] volts3 = time3 ** -2 ax.set_xlabel("Volts (v)") ax.set_ylabel("Time (s)") ax.set_title("Fun Plot") ax.plot(time, volts, '.b')

20

[<matplotlib.lines.Line2D at 0x7fd5a7094430>]

<Figure size 864x360 with 0 Axes>

Saving plots as graphics is a simple call to the method

```
fig.savefig(fileName, dpi=dotsPerInch)
```

where the argument `dpi=dotsPerInch`

is optional. The type of file produced is determined by the extension of the file name. Here are the file types I suggest:

`.png`

with`dpi=200`

- this makes a nice large file you can include in any document. The quality comes out better than if you use a`.jpg`

file.`.svg`

with not`dpi`

- this is a*vector*image file. Everything is describes by coordinates and sizes. This file scale to differnt sizes very well. This is a good choice if you are making a poster with large figures.`.pdf`

with`dpi=200`

- sometimes this format works better with LaTeX documents.

I usually use `.png`

format files. In the cell below save the previous pair of plots in this format.

BTW, jupyter remembers the previous plot, so you can just run the `savefig`

code.

21

In [12]:

fig.savefig(Yay2.csv, dpi=dotsPerInch)

22

```
---------------------------------------------------------------------------
```

```
NameError Traceback (most recent call last)
```

```
<ipython-input-12-f890cc8ad872> in <module>
----> 1 fig.savefig(Yay2.csv, dpi=dotsPerInch)
```

```
NameError: name 'Yay2' is not defined
```

** Double Click Here to edit this hidden cell **
Here is your figure in this web page. Edit the name to match your file name. Then execute this cell by typing `<shift><enter>`

.

23

*Histograms* are a powerful way of graphing data that has randomness around some value. It shows how the data are randomly distributed. The x-axis are the data values, and the y-axis is a bar graph of how many times each value occurs.

The code below simulates measuring a lenth of 5 cm ten thousand times with an uncertainty of 0.1 cm.

```
np.random.seed(0)
meas1 = np.random.normal(5.0, 0.1, 10000)
```

The basic histogram method is (after you have made a figure and an axis) is `ax.hist(data)`

, where `data`

are the numbers you want to make a histogram of.

Create a figure and axes, and plot this histogram.

24

In [25]:

fig = plt.figure() ax = fig.add_subplot(111) data = [10,20,30,40,50,55,60,65,70,50,40,30,10,5] ax.hist(data) np.random.seed(0) meas1 = np.random.normal(5.0, 0.1, 10000)

25

You might note that this distribution only kind of looks like the normal (or Gaussian) distribrution you have seen before.

The most common modification to the default hostogram plot is to change the bins on the x-axis. One way is to add more bins by adding a second argument rifht after your data that is an integer setting the number of bins.

Replot the above data with 100 bins. When you do, you should see more small tails in the histogram and it will look more like the classical normal distribution.

26

In [26]:

fig = plt.figure() ax = fig.add_subplot(111) data = [10,20,30,40,50,55,60,65,70,50,40,30,10,5] ax.hist(data) ax.hist(data, bins=100) np.random.seed(0) meas1 = np.random.normal(5.0, 0.1, 10000)

27

Finally, there is an optional argument `log=True`

that make the y-axis logarithmic. In the cell below, plot the above histogram with the log scale turned on.

28

In [ ]:

29

Finally you can provide a list of bin boundaries as an array. The following example simulates the rolling of a pair of dice. You know there only 11 possible values from "snake eyes" or 2 to "boxcars" or 12. The default `hist`

doesn't get his right without helping it out. This examples feeds it the histogram boundries.

Finally, this example demonstrates the `normed`

keyword that normalized the numbers so, like a probability density, the sum adds up to 1.0.

30

In [ ]:

31

Here are some other topic you can explore on your own. I go to a web browser and google `matplotlib whatever`

to find things out or refresh my memory.

`lw`

- line width`ms`

- marker size`mfc`

- marker face color`mec`

- marker edge color`mew`

- marker edge width

- names - 'red', etc. But also X11 colors like 'DodgeBlue'
- hex - '#ff8022' in rrggbb format
- RGB tuples - like
`color=(0,0,1)`

, rgb values range from 0 to 1 - RGBA tuple - like
`color=(0,1,.5,.3)`

where A is transparency

The basic call is `ax.text(x,y,string)`

32

In [1]:

from IPython.core.display import HTML def css_styling(): styles = open("custom.css", "r").read() return HTML(styles) css_styling()

33