INST326 In-Class Exercises

20170615, Matplotlib and Hashing

These exercises cover using Matplotlib, for plotting points and making graphs, and developing some simple hashing functions to handle various types.


Matplotlib Introduction

Matplotlib is probably the single most used Python package for 2D-graphics. It provides both a very quick way to visualize data from Python and publication-quality figures in many formats. We are going to explore matplotlib in interactive mode covering most common cases.

For interactive matplotlib sessions with Matlab/Mathematica-like functionality, we use Jupyter with its special Matplotlib mode that enables non-blocking plotting.

In the Jupyter notebook, we insert, at the beginning of the notebook the following magic:

%matplotlib inline
In [2]:
# Activate the inline, interactive graphics functions in Jupyter
%matplotlib inline

pyplot

pyplot provides a procedural interface to the matplotlib object-oriented plotting library. It is modeled closely after Matlab™. Therefore, the majority of plotting commands in pyplot have Matlab™ analogs with similar arguments.

In [3]:
# READING CHECK: Uncomment the following lines to enable matplotlib
import matplotlib.pyplot as plt

Simple Plotting

The plt variable exposes all the procedural plotting commands we need to do some basic plotting. We'll show an example below.

In [4]:
plt.plot([1,2,3,4])
plt.xlabel('X Axis')
plt.ylabel('Y Axis')
plt.show()

You may be wondering why the x-axis ranges from 0-3 and the y-axis from 1-4. If you provide a single list or array to the plot() command, matplotlib assumes it is a sequence of y values, and automatically generates the x values for you. Since python ranges start with 0, the default x vector has the same length as y but starts with 0. Hence the x data are [0,1,2,3].

plot() is a versatile command, and will take an arbitrary number of arguments. For example, to plot x versus y, you can issue the command:

In [5]:
plt.plot([1, 2, 3, 4], [1, 4, 9, 16])
plt.show()

For every x, y pair of arguments, an optional third argument sets the format string that indicates the color and line type of the plot. The letters and symbols of the format string are from MATLAB, and you concatenate a color string with a line style string. The default format string is ‘b-‘, which is a solid blue line.

To alter this plot and draw with red circles, use the following code:

In [6]:
plt.plot([1,2,3,4], [1,4,9,16], 'g*-')
plt.axis([0, 6, 0, 20])
plt.show()

Colors in Matplotlib

A concise listing of color information can be found on this page: https://matplotlib.org/users/colors.html

Forcing Matplotlib to Plot

After plotting your data, you need to call plt.show() to make Matplotlib render your image.


Exercise 1 - Plotting

Use the code above and the range() function to plot the following functions on the domain [-10, 10]:

  1. $y = x$
  2. $y = x^2 -4x + 4$
  3. $y = \sqrt{x}$
  4. $y = sin(x)$

Note, you will need the math library for sin().

In [7]:
import math

help(math.sin)
Help on built-in function sin in module math:

sin(...)
    sin(x)
    
    Return the sine of x (measured in radians).

I've provided an example of plotting $y = x^2$ below for the domain [0, 4].

In [8]:
y = []
x = range(5)
for x1 in x:
    y.append(x1**2)
    
plt.plot(x, y)
plt.show()

PROVIDE YOUR PLOTTING IMPLEMENTATIONS HERE

In [9]:
# Plot y = x
y = []
x = []

for i in range(-10, 11):
    x.append(i)
    y.append(i)
    
plt.plot(x, y)
plt.show()
In [12]:
# Plot y = x**2 - 4x + 4
y = []
x = []

for i in range(-10, 11):
    x.append(i)
    y.append(i ** 2 - 4 * i + 4)
    
plt.plot(x, y)
plt.show()
In [13]:
# Plot y = \sqrt{x}
y = []
x = []

# NOTE: Square root is not defined for x<0
for i in range(0, 11):
    x.append(i)
    y.append(math.sqrt(i))
    
plt.plot(x, y)
plt.show()
In [12]:
# Plot something
y = []
x = []

for i in range(-10, 11):
    x.append(i)
    y.append(math.sin(i))
    
plt.plot(x, y)
plt.show()

Exercise 2 - Plotting Smoother Curves

Your sine curve is likely not very pretty. To make it smoother, we need to be more intelligent about how we generate $x$-values. Using range() yields only integers, and we need higher fidelity.

Use the range() function to generate 40 $x$-values between 0 and 10. You can do this by creating a counting variable, looping through range(40), and incrementing this counting variable by 0.25. Use these values as your input to the sin() function and plot the results.

In [13]:
# Plot all the things
y = []
x = []

xCount = 0.0
for i in range(40):
    # add x and sin(x) to x and y
    x.append(xCount)
    y.append(math.sin(xCount))
    xCount += 0.25
    

plt.plot(x, y)
plt.show()

Exercise 3 - Plotting Multiple Curves

Matplotlib will plot multiple curves on the same plot as long as you don't call plt.show() between calls to plt.plot(). Use your code for plotting sines in exercise 2 to plot both a sine and cosine curve in the same domain and on the same plot by calling plt.plot() twice. Your plot() calls should use the same list of x values but different y values.

In [14]:
# Plot all the things
y1 = []
y2 = []
x = []

# Implement here


xCount = 0.0
for i in range(40):
    # add x and sin(x) to x and y
    x.append(xCount)
    
    y1.append(math.sin(xCount))
    y2.append(math.cos(xCount))
    
    xCount += 0.25
    
# Plot the two curves
plt.plot(x, y1)
plt.plot(x, y2)


# Make sure the statement below is last
plt.show()

Exercise 4 - Changing Colors and Adding Labels

Take your code from exercise 3 and use the color= named argument in the plot() function to change the color of the sine curve to "red" and the cosine curve to "green". Also, use the label= named argument in plot() to set the label of each curve to "sin(x)" and "cos(x)" respectively.

NOTE: The call to plt.legend() at the bottom of the code cell causes a legend with the line names to be displayed. If no lines are given, the legend not print, and you will receive a UserWarning.

In [15]:
# Plot all the things
plt.plot(x, y1, "r*-", label="Sine")
plt.plot(x, y2, color="g", label="Cosine")


# Make sure the statement below is last
plt.legend()
plt.show()

Histograms

Matplotlib can do many kinds of plots.

One particularly useful type of plot for us will be histograms, which show relative frequencies of values in a range. Here's an example of a histogram:

Exercise 5 - Plotting Histograms

Using Python's random library and the random.random() function, create a list of 100 random numbers. Then, call plt.hist() with that list to see the frequencies of different values.

In [22]:
import random

x = []

# Implement here
for i in range(100):
    x.append(random.random())
    
plt.hist(x, bins=10)
plt.show()

This plot doesn't look very interesting, as it should be mostly uniform. That is, the random.random() function should return values uniformly sampled from the range [0,1].

To make this graph look more like the example histogram, use the random.normalvariate(0,1) function. NOTE the arguments to the function, which represent the mean and standard deviation of a normal distribution.

In [15]:
import random

x = []

# Implement here
for i in range(100):
    x.append(random.normalvariate(0,1))
    
plt.hist(x, bins=100)
plt.show()

We can do interesting things with the histogram, like visualize relative frequencies for letters in the alphabet (may be relevant to your homework).

I've shown an example of this below.

In [19]:
import requests # So we can pull from a website
import string # for ascii letters

# Get the text of the Hack Manifesto, "The Conscience of a Hacker"
manifestoText = requests.get("https://dl.dropboxusercontent.com/u/66442241/manifesto.txt").text.lower()

# Convert it to a list of characters
characterList = list(manifestoText)

# Remove anything that isn't in the list of ascii letters
alphabeticOnly = filter(lambda x: x in string.ascii_lowercase, characterList)

# Plot after converting letters to numbers and correcting to zero
plt.hist([ord(x)-97 for x in alphabeticOnly], bins=26)

# Set the X tick marks to actual letters rather than numbers
plt.xticks(range(26), list(string.ascii_lowercase))
plt.show()
In [ ]: