A few python, numpy, and matplotlib examples

Marty Ligare. August 2020

Cells

This is a markdown cell. Markdown cells are for for formatted comments. See the Markdown Cheat-Sheet for more information.

If you single-click on a cell you can get a box around the cell, and you can see what kind of cell it is in the menu bar above (Markdown, code, etc.), and you can change it.

Double click on this cell, and we'll make some changes. Let's add math: $e^{i\pi} = -1$

Shift+Enter to execute cells.

Importing modules

Functions from modules imported in this manner must be preceded by the "name" given to the module (np, plt), e.g., np.zeros() below.

In [2]:
import numpy as np
import matplotlib.pyplot as plt

The following is an Ipython "magic" command that places plots into notebooks, and makes the plots interactive.

In [3]:
%matplotlib notebook

Simple loops

In [4]:
for i in range(5):
    print(i)
0
1
2
3
4
In [5]:
for i in range(4,10):
    print(i)
4
5
6
7
8
9
In [6]:
for i in range(4,10,2):
    print(i)
4
6
8
In [7]:
i = -2
while i < 5:
    print(i)
    i += 1
-2
-1
0
1
2
3
4

Conditionals

In [8]:
i = 5

if i<4:
    print("ok")
    
elif i == 4:
        print("better")
    
else:
        print('not ok')
not ok

Constructing arrays

Numpy arrays are easy-to-use "containers" for data that are computationally efficient.

Constructing 1-D arrays "by hand"

In [9]:
a = np.array([10, 20, 30, 4.e1])
print(a)
[10. 20. 30. 40.]

Constructing arrays using numpy "built-ins" (see the numpy array tip sheet)

In [10]:
b = np.zeros(10)
print(b)
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
In [11]:
b = np.zeros((10,10))
print(b)
[[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]]
In [12]:
c = np.eye(4,4)
print(c)
[[1. 0. 0. 0.]
 [0. 1. 0. 0.]
 [0. 0. 1. 0.]
 [0. 0. 0. 1.]]

Constructing arrays using numpy looping features (similar to Mathematica Table command)

In [13]:
d = np.array([i*i for i in range(100) if i%2==1])
print(d)
[   1    9   25   49   81  121  169  225  289  361  441  529  625  729
  841  961 1089 1225 1369 1521 1681 1849 2025 2209 2401 2601 2809 3025
 3249 3481 3721 3969 4225 4489 4761 5041 5329 5625 5929 6241 6561 6889
 7225 7569 7921 8281 8649 9025 9409 9801]

Constructing arrays using the numpy linspace function

Especially useful in making points along independent axis in graphs.

In [14]:
np.linspace(4,6,11)
Out[14]:
array([4. , 4.2, 4.4, 4.6, 4.8, 5. , 5.2, 5.4, 5.6, 5.8, 6. ])

Manipulating arrays

In [15]:
a = np.array([1,2,3,4])
b = np.array([5,6,7,8])

Notice the element-wise behaviour of operators -- No need for loops

In [16]:
a**2
Out[16]:
array([ 1,  4,  9, 16])

The * gives element-by-element multiplication

In [17]:
a*b
Out[17]:
array([ 5, 12, 21, 32])

The @ operator gives matrix multiplication (here, the dot product)

In [18]:
a@b
Out[18]:
70

array indexing starts at 0; negative indices wrap around "to the left"

In [19]:
a[0], a[-1]
Out[19]:
(1, 4)

"Slice" arrays using colons (:)

In [20]:
a[1:], a[:3]
Out[20]:
(array([2, 3, 4]), array([1, 2, 3]))

Combine arrays into higher-dimensional arrays

In [21]:
c = np.array([a,b])
print(c)
[[1 2 3 4]
 [5 6 7 8]]

Extract the second column of the 2-d array c (Take the transpose of c and extract 2nd element)

In [22]:
np.transpose(c)[1]
Out[22]:
array([2, 6])

Defining functions

Simple function of two variables

In [23]:
def f(x,y):
    '''Comments about a function go here; they are called a 'docstring'. 
    This function returns the product of x and y.'''
    return x*y
In [24]:
f(3,4)
Out[24]:
12

Getting help, i.e., reading contents of a docstring

In [25]:
f?
In [26]:
np.linspace?

Functions can act on arrays too!

In [27]:
a = np.linspace(1,10,10)
f(a,.5)
Out[27]:
array([0.5, 1. , 1.5, 2. , 2.5, 3. , 3.5, 4. , 4.5, 5. ])

Making simple graphs

In [28]:
plt.figure()
x = np.linspace(0,5,201)  # Make a pseudo-continuous set of x-values
y = x**2                  # y values for smooth function
plt.plot(x,y)
xdata = np.array([1,2,3,4,5])# Discrete x-values
ydata = xdata**2               # y-values for discrete data set
plt.scatter(xdata,ydata);

Adding features to graphs

In [29]:
plt.figure()
plt.axhline(0, color='magenta')
plt.axvline(0, color='magenta')
plt.title("My theory")
plt.xlabel('$x$')
plt.ylabel('$\sigma$')
plt.grid()
x = np.linspace(0,5,201)
y = x**2
plt.plot(x,y, label="theory")
xdata = np.array([1,2,3,4,5])
ydata = xdata**2
plt.scatter(xdata,ydata)
plt.legend()
plt.xlim(-2,7);

Graphs with error bars

In [30]:
plt.figure()
plt.axhline(0, color='magenta')
plt.axvline(0, color='magenta')
plt.title("My theory")
plt.xlabel('$x$')
plt.ylabel('$\sigma$')
plt.grid()
x = np.linspace(0,5,201)
y = x**2
plt.plot(x,y, label="theory")
xdata = np.array([1,2,3,4,5])
ydata = np.array([1.3, 3.5, 9.4, 15.5, 24])
u = np.ones(len(xdata))*0.8
plt.errorbar(xdata, ydata, yerr=u, fmt='o',label='data')
plt.legend()
plt.xlim(-2,8);

Writing arrays to a data file; reading in a data file as an array

In [31]:
a = np.loadtxt('sample.dat')
print(a)
[[  0.          11.54783245   5.        ]
 [  1.           4.91397218   5.        ]
 [  2.          13.79656022   5.        ]
 [  3.           4.8967277    5.        ]
 [  4.           5.28860655   5.        ]
 [  5.          -5.92667458   5.        ]
 [  6.          -7.97324545   5.        ]
 [  7.         -17.72641975   5.        ]
 [  8.         -27.30315991   5.        ]
 [  9.         -34.8949771    5.        ]
 [ 10.         -54.88526451   5.        ]]
In [32]:
b  = a**2
print(b)
[[0.00000000e+00 1.33352434e+02 2.50000000e+01]
 [1.00000000e+00 2.41471226e+01 2.50000000e+01]
 [4.00000000e+00 1.90345074e+02 2.50000000e+01]
 [9.00000000e+00 2.39779421e+01 2.50000000e+01]
 [1.60000000e+01 2.79693593e+01 2.50000000e+01]
 [2.50000000e+01 3.51254716e+01 2.50000000e+01]
 [3.60000000e+01 6.35726431e+01 2.50000000e+01]
 [4.90000000e+01 3.14225957e+02 2.50000000e+01]
 [6.40000000e+01 7.45462541e+02 2.50000000e+01]
 [8.10000000e+01 1.21765943e+03 2.50000000e+01]
 [1.00000000e+02 3.01239226e+03 2.50000000e+01]]
In [33]:
np.savetxt('output.dat',b)

Version Information

version_information is from J.R. Johansson (jrjohansson at gmail.com); see Introduction to scientific computing with Python: http://nbviewer.jupyter.org/github/jrjohansson/scientific-python-lectures/blob/master/Lecture-0-Scientific-Computing-with-Python.ipynb for more information and instructions for package installation.

If version_information has been installed system wide (as it has been on Bucknell linux computers with shared file systems), continue with next cell as written. If not, comment out top line in next cell and uncomment the second line.

In [34]:
%load_ext version_information
In [35]:
version_information numpy, matplotlib
Out[35]:
SoftwareVersion
Python3.7.7 64bit [GCC 7.3.0]
IPython7.16.1
OSLinux 3.10.0 1062.9.1.el7.x86_64 x86_64 with centos 7.7.1908 Core
numpy1.18.5
matplotlib3.3.0
Wed Aug 05 15:12:42 2020 EDT
In [ ]: