% TODO revise

% Matplotlib
%
% CSE/IT 107: Introduction to Programming
% New Mexico Tech
%
% Prepared by Stephanie Gott and Roguh
% Fall 2016
\documentclass[11pt]{cselabheader}

% Define title and author
\newcommand{\thelabnumber}{11}
\newcommand{\thetitle}{Rendering Plots With Matplotlib}
\newcommand{\theauthor}{CSE/IT 107L}

% Write title and author
\title{\thetitle}
\author{\theauthor}
\date{NMT Department of Computer Science and Engineering}

\fancyhead[R]{Lab \thelabnumber: \thetitle}
\fancyhead[L]{\theauthor}

\makehyperref
\makeindex[title=Index of New Functions and Methods, intoc]

\begin{document}

\pagenumbering{roman}
\maketitle
\hrule

\begin{quote}
``The greatest value of a picture is when it forces us to notice what we
never expected to see.''
\end{quote}
\begin{flushright}
---John Tukey
\end{flushright}

\begin{figure}[H]
  \centering
  \includegraphics[width=\textwidth]{img/xkcd_self_description.png}
  \caption{Self description. \url{https://xkcd.com/688/}}
\end{figure}

\hrule

\pagebreak
\tableofcontents

\section*{Introduction}
\addcontentsline{toc}{section}{Introduction}
In this lab you will learn about generating 2D graphics using
Matplotlib.  This is a powerful Python library that can be used to
create detailed visualizations such as scatter plots and
histograms. You will learn about Python's list comprehensions, which
help when modifying lists of data.  There's also an extra credit where
you use the built-in CSV module to read CSV files.  The key lesson
this lab should teach you is to read Python library
documentation. With this skill you can learn to use many of Python's
free and open-source libraries.

\pagebreak
\pagenumbering{arabic}
\section{Keyword Arguments}
Before we start, you should know about a commonly used Python feature
called keyword arguments. As you know, functions may take zero or more
required arguments, these are called \textsl{positional arguments}.
There is a special syntax that can be used to define \textsl{optional
arguments.}

For example, this function takes either one or two arguments. The second
argument has a default value of 5.

\begin{pyconcode}
>>> def f(fst, snd = 5):
...    return fst * snd
>>> f(10)
50
>>> f(10, 6)
60
>>> f()
Traceback (most recent call last):
  File ``<stdin>'', line 1, in <module>
TypeError: f() missing 1 required positional argument: 'fst'
\end{pyconcode}

An important feature is that keyword arguments may be labeled
and listed in any order when calling the function. For example,
the following function takes two keyword arguments. There are five
valid ways to call this function. You may pass no arguments, then
the default values aare used. You may pass either argument by itself
or you may pass both arguments in any order.

\begin{pyconcode}
>>> def p(greeting="Hello", subject="world"):
...     return "{} {}".format(greeting, subject)
>>> p()
"Hello world"
>>> p(greeting="Goodbye")
"Goodbye world"
>>> p(subject="humans")
"Hello humans"
>>> p(greeting="Bonjour", subject="le monde")
"Bonjour le monde"
>>> p(subject="le monde", greeting="Bonjour")
"Bonjour le monde"
\end{pyconcode}

% \section{Numpy Arrays}
% Before we can use Matplotlib, we must learn about a new datatype:
% Numpy arrays.  These are efficient containers for numeric data and
% prefered when plotting data using Matplotlib. There are several ways
% to construct these arrays. The \pythoninline{numpy.array()} function
% can be used to convert a Python list into an array.
%
%   \begin{pyconcode}
% >>> import numpy
% >>> xs = numpy.array([1,2,3])
% array([1, 2, 3])
% >>> ys = numpy.array([8,4,7])
% array([8, 4, 7])
%   \end{pyconcode}
%
% The \pythoninline{numpy.linspace} can be used to create evenly spaced values.
% For example, if we want 10 points between 0 and 1 (inclusive), we can type:
%   \begin{pyconcode}
% >>> import numpy
% >>> numpy.linspace(0, 10, num=5)
% array([0, 2.5, 5, 7.5, 10])
%   \end{pyconcode}
%
% You can add or multiply two arrays element-by-element, and you can
% apply other mathematical functions to arrays. For example, the
% \pythoninline{numpy.sqrt} function can be used to find the square root
% of each element in the array.
%   \begin{pyconcode}
% >>> import numpy
% >>> xs = numpy.linspace(0, 1, num=5)
% array([0, 2.5, 5, 7.5, 10])
% >>> os = numpy.linspace(-20, 0, num=5)
% array([-20, -15, -10, -5, 0])
% >>> xs + os
% array([-20, -12.5, -5, 2.5, 10])
% >>> xs * os
% array([0, -37.5, -50, -37.5, 0])
% >>> numpy.sqrt(xs)
% array([0, 1.58113883, 2.23606798, 2.73861279, 3.16227766])
% >>> numpy.sin(os)
% array([-0.91294525, -0.65028784, 0.54402111, 0.95892427, 0])
%   \end{pyconcode}
%
% The \pythoninline{numpy.arange} function is similar to Python's
% \pythoninline{range} function. It improves on the built-function by
% generating values spaced by non-integers.
%
% \begin{pyconcode}
% >>> import numpy
% >>> numpy.arange(0, 10)
% array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
% >>> numpy.arange(0, 12, 3)
% array([0, 3, 6, 9])
% >>> numpy.arange(0, 4, 0.5)
% array([0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5])
% \end{pyconcode}

\section{Matplotlib}

Matplotlib is a Python 2D plotting library which produces publication
quality figures in a variety of formats and interactive environments.
We will be using the \pythoninline{matplotlib.pyplot} library. It is
commonly renamed to \pythoninline{plt} using this code:

\begin{pyconcode}
>>> import matplotlib.pyplot as plt
\end{pyconcode}

It's a good idea to keep the Matplotlib documentation on hand as you read these
examples. All of the following matplotlib functions are documented online at:
\begin{center}
\url{http://matplotlib.org/api/pyplot_api.html}
\end{center}

\subsection{Plotting Points with the \protect{\pythoninline{plot}} Function}

\pythoninline{plt.plot} is a versatile function that is used to plot
pairs of numeric values. Matplotlib does not take a list of tuples
representing points, instead it takes two lists. The list of values on
the x-axis are the first argument and the list of y-axis values form
the second argument. One of the lists must be in ascending order.

\begin{pyconcode}
>>> import matplotlib.pyplot as plt
>>> plt.plot([1, 2, 3, 4], [10, -10, 40, 50])
>>> plt.show()
\end{pyconcode}

The \pythoninline{plt.show()} function shows everything drawn by
previously called plotting functions. This image was draw by
the previous Matplotlib code:

\begin{center}
\includegraphics[width=0.85\textwidth]{img/matplotlib_plot1.png}
\end{center}

Matplotlib plots can be modified in many ways. The documentation has a
table of keyword arguments for this function. The columns are Property
and Description.  Let's try some of those. The \pythoninline{color},
\pythoninline{linestyle}, and \pythoninline{marker} keyword arguments
can be used to draw a differently styled line.  As of March, 2016 the
Matplotlib documentation for these functions, colors, and line styles
are located at

\begin{center}
\url{http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.plot}

\url{http://matplotlib.org/api/colors_api.html}

\url{http://matplotlib.org/api/lines_api.html#matplotlib.lines.Line2D.set_linestyle}
\end{center}

Here's the same plot with a red, dashed line and o's on every data point.

\begin{center}
\includegraphics[width=0.85\textwidth]{img/matplotlib_plot2.png}
\end{center}

\begin{pyconcode}
>>> import matplotlib.pyplot as plt
>>> plt.plot([1, 2, 3, 4, 5], [10, -10, 40, 50, 60],
...          color='red', linestyle='dashed', marker='o')
>>> plt.show()
\end{pyconcode}

\subsection{Histograms using the \protect{\pythoninline{hist}}
Function}

Matplotlib's \pythoninline{plt.hist()} can draw the histogram of a
list, which shows how often a value occurs.

\begin{pyconcode}
>>> import matplotlib.pyplot as plt
>>> plt.hist([1, 1, 1, 1.2, 1.3, 1.9, 1.9, 2, 2.1, 2.5])
>>> plt.show()
\end{pyconcode}

\begin{center}
\includegraphics[width=0.85\textwidth]{img/matplotlib_hist1.png}
\end{center}

The \pythoninline{bins} argument is used to draw fewer bins of
data. The histogram is rotated by passing
\pythoninline{orientation='horizontal'}. See the documentation at:

\begin{center}
\url{http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.hist}
\end{center}

\begin{pyconcode}
>>> import matplotlib.pyplot as plt
>>> plt.hist([1, 1, 1, 1.2, 1.3, 1.9, 1.9, 2, 2.1, 2.5]),
...          bins=4, orientation='horizontal', color='red')
>>> plt.show()
\end{pyconcode}

\begin{center}
\includegraphics[width=0.85\textwidth]{img/matplotlib_hist2.png}
\end{center}

\subsection{Scatter plots with \protect{\pythoninline{scatter}} Function}

Scatter plots may be generated using the \pythoninline{plt.scatter}
function.  These plots should be given three arguments
\pythoninline{x, y, s}; these are arrays indicating the x and y values
of the data and the size of each data point.  The \pythoninline{c} and
\pythoninline{alpha} keyword arguments can be used to modify color and
opacity of data points. Colors are automatically picked if an array of
values is given. Documentation available at

\begin{center}
\url{http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.hist}
\end{center}

This plots data with x-values from 0 to 10, randomly generated
y-values between 0 and 10, and sizes between 1200 and 30 with some variation.
The color scheme is automatically picked according to size.

\begin{pyconcode}
>>> import random
>>> import matplotlib.pyplot as plt
>>> x = [x + 1 for x in range(0, 10)]
>>> y = [(elem + random.random() * 10) % 10 for elem in x]
>>> sizes = [200 * elem + random.random() * 9300 for elem in x]
>>> plt.scatter(x, y, s=sizes, c=sizes, alpha=0.8)
>>> plt.show()
\end{pyconcode}

\begin{center}
\includegraphics[width=0.8\textwidth]{img/matplotlib_scatter.png}
\end{center}

\subsection{Bar Plots with the \protect{\pythoninline{bar}} Function}

Matplotlib can draw a plot of rectangles, each one bounded by the four edges:
\pythoninline{left}, \pythoninline{left + width}, \pythoninline{bottom}, and
\pythoninline{bottom + height}. Here's a demonstration using the
\pythoninline{color} and \pythoninline{edgecolor} keyword arguments.
Documentation is here:

\begin{center}
\url{http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.bar}
\end{center}


The rectangles have randomly generated heights and the same width and space
between them.

\begin{pyconcode}
>>> import random
>>> import matplotlib.pyplot as plt
>>> lefts = [x for x in range(0,100,5)]
>>> print(lefts)
[0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95]
>>> heights = [x + random.random()*50 + 10 for x in range(0,20)]
>>> print(heights)
[49.714391342616054, 19.172956449982053, 26.30296873725814, 35.617456459379966,
 41.00284816312063, 36.42499187921262, 20.105984017686016, 34.56418052389644,
 24.48833113475763, 54.51007088879054, 51.26910728592864, 27.689576280094144,
 67.57824233176122, 41.335596453966545, 47.96576291980089, 45.292422625538435,
 34.460458928440374, 31.992222247836935, 65.24156104706233, 66.47014183737392]
>>> plt.bar(left=lefts, height=heights, width=4.5, bottom=0,
...         color='lightblue', edgecolor='blue')
>>> plt.show()
\end{pyconcode}

\begin{center}
\includegraphics[width=0.85\textwidth]{img/matplotlib_bar.png}
\end{center}

\subsection{Drawing Many Plots with the \protect{\pythoninline{subplot}}
Function}

If you want to draw many plots in the same figure, use the
\pythoninline{plt.subplot} function to split the figure into several rows
and columns. The first and second arguments are the number of rows and columns.
The third argument is the figure number, this should be between 1 and
rows * columns. Documentation available at

\begin{center}
\url{http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.subplot}
\end{center}

Here we draw 4 plots, three \pythoninline{plt.plot}s and one
\pythoninline{plt.hist} at the bottom corner.

\begin{python3code}
import random
import matplotlib.pyplot as plt

x = [elem for elem in range(0,10)]
y = [random.random() for elem in x]

plt.subplot(2, 2, 1)
plt.plot(x, y)

plt.subplot(2, 2, 2)
#plt.plot(x, 0.5 * x ** 2)
plt.plot(x, [elem ** 2 * 0.5 for elem in x])

plt.subplot(2, 2, 3)
#plt.plot(x, y * x ** 2)
plt.plot(x, [elem * index ** 2 for index, elem in enumerate(y)])

plt.subplot(2, 2, 4)
plt.hist(y)

plt.show()
\end{python3code}

\begin{center}
  \includegraphics[width=\textwidth]{img/matplotlib_subplot.png}
\end{center}

\subsection{Describing your Plots}
See these links for documentation:
\begin{center}
\url{http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.xlabel}

\url{http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.ylabel}

\url{http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.title}

\url{http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.subplot}
\end{center}

Plots can be labeled and titled using the
\pythoninline{plt.xlabel},
\pythoninline{plt.ylabel},
and \pythoninline{plt.title} functions.
Here's an example:

\begin{python3code}
import random
import matplotlib.pyplot as plt
x = [x + 3 for x in range(0,52,2)]
y = [random.random() * x + x for x in x]

plt.plot(x, y)
plt.xlabel('Time spent coding')
plt.ylabel('Winning')
plt.title('Data plot.')
plt.show()
\end{python3code}

\begin{center}
  \includegraphics[width=0.85\textwidth]{img/matplotlib_labeled1.png}
\end{center}

What if you want to call attention to an individual data point? Then
you should consider the \pythoninline{plt.annotate} function to add
annotations to plots.  In this example we indicate the maximum y-value
in a randomly generated set of data: This code produces a labeled,
annotated plot.

Annotation text is set with the \pythoninline{s} argument. The arrow
is styled using the \pythoninline{arrowprops} argument.  The
\pythoninline{xy} and \pythoninline{xytext} keyword arguments are used
to place the arrow and text.

\begin{python3code}
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 50, num=20)
y = np.random.random(20) * x + x

# find maximum
maximum_index = np.argmax(y)
maximum = y[maximum_index]

plt.plot(x, y)
plt.xlabel('Time spent coding')
plt.ylabel('Winning')
plt.title('Data plot.')

# add annotation at maximum point
plt.annotate(s='Maximum value is {:.3}'.format(y[maximum_index]),
             xy=(x[maximum_index], y[maximum_index]),
             xytext=(x[maximum_index] * 0.6, y[maximum_index] * 0.9),
             arrowprops={'arrowstyle': "wedge,tail_width=0.25"})

plt.show()
\end{python3code}

\begin{center}
\includegraphics[width=0.85\textwidth]{img/matplotlib_labeled2.png}
\end{center}

The tick labels can be changed using the \pythoninline{plt.xticks} and
\pythoninline{plt.yticks} functions. The first argument is a list of
numbers and the second argument is the list of labels for each value.
For example,
\begin{pyconcode}
>>> plt.plot([1, 2, 3], [400, -100, 20])
>>> plt.xticks([1, 2, 3], ["Group 1", "Group 2", "Control"], rotation=-45)
>>> plt.show()
\end{pyconcode}

\begin{center}
\includegraphics[width=0.85\textwidth]{img/matplotlib_xticks.png}
\end{center}

\subsection{Subplots and Annotations}

Here's an example where subplots have annotations and titles.

\begin{python3code}
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y1 = [4, 8, 2, 6, 0]
y2 = [14, 2, 8, 0, 1]

plt.subplot(1, 2, 1)
plt.plot(x, y1)
plt.annotate(s='Here is an 8', xy=(2, 8), xytext=(3,7),
             arrowprops={'arrowstyle': "wedge,tail_width=0.25"})
plt.title('Dataset 1')

plt.subplot(1, 2, 2)
plt.plot(x, y2)
plt.annotate(s='Here is another 8', xy=(3, 8), xytext=(2,9),
             arrowprops={'arrowstyle': "wedge,tail_width=0.25"})
plt.title('Dataset 2')

plt.show()
\end{python3code}

\begin{center}
\includegraphics[width=\textwidth]{img/matplotlib_labeledsubplot.png}
\end{center}

\subsection{Overlaying Plots}
Plots may be overlayed by calling plot functions multiple times.
For example, here are plots of two data sets on the same figure.
There is also a line drawn at y=8.

\begin{python3code}
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y1 = [4, 8, 2, 6, 0]
y2 = [14, 2, 8, 0, 1]

plt.plot(x, y1)
plt.plot(x, y2)
plt.plot([1,5], [8,8])
plt.title('Datasets 1 and 2')

plt.show()
\end{python3code}

\begin{center}
\includegraphics[width=\textwidth]{img/matplotlib_overlayed.png}
\end{center}

\subsection{Saving Plots to a File Using \pythoninline{plt.savefig}}
To save a plot to a file, replace \pythoninline{plt.show()} with a call to
the \texttt{savefig} function:

\begin{python3code}
plt.plot([1, 2, 3], [4, 5, 6])
plt.title('Silly plot')
plt.savefig('plot.png')
\end{python3code}

You can save to different formats by changing the extension of the filename.
For example, the function would produce a JPG file when given a parameter
``filename.jpg''.

\section{Exploring APIs}
An important part of this lab is reading module documentation. You
have already seen one third party module (Matplotlib), and
built-in modules such as \pythoninline{math}. Almost every good Python
module has good documentation and if you want to learn how to use one
you should start by reading its documentation.  For example, Matplotlib
supports animation, image rendering, stream plots, error plots,
contour plots, log scaled axis, and many other features. You can see
examples and detailed specifications in the Matplotlib docs.

\subsection{Other Libraries}
Other powerful, third-party and well-documented Python modules include
\begin{inparaenum}
\item \textsl{Scrapy:} a web crawling library.
\item \textsl{Newspaper:} an Easy to use natural language processor and news downloader.
\item \textsl{astropy:} astronomy and astrophysics packages.
\item \textsl{vtk:} highly functional 3D visualization library.
\item \textsl{pillow:} the friendly fork of the Python Imaging Library.
\item \textsl{OpenCV:} a computer vision library.
\item \textsl{Django:} used to deliver and manage dynamic websites; powers many large websites.
\end{inparaenum}

Visit their websites for information on usage and installation.
Here's a list of more interesting libraries:
\begin{center}
\url{https://github.com/vinta/awesome-python}
\end{center}

\newpage
\section{Exercises}\label{exercises}

\begin{warningbox}{Labels}
  Remember to label your axes using
  \pythoninline{plt.xticks()} and \pythoninline{plt.yticks()}
  and title your graph
  using \pythoninline{plt.title()}. Read the documentation to
  find out more.
\end{warningbox}

\begin{ex}[plotpoints.py] 
Plot the following points. Add labels, a title, and an annotation to the plot
as shown in the example. Make sure to draw a dashed blue line.
The annotation contains the text ``max'' and is located at the point (2, 20).
The annotation text must be slightly below and the arrow connecting the text
and point must be black and have width set to 2.

\begin{python3code}
xs = range(-5, 15)
ys = [-(x - 2) ** 2 for x in xs]

...

plt.title('Plot of $-(x - 2)^2$')
\end{python3code}

\begin{center}
\includegraphics[width=0.8\textwidth]{img/basic.png}
\end{center}

You may use \pythoninline{arrowprops={'color': 'black', 'width': 2}}
when drawing the annotation.
\end{ex}

\begin{ex}[scorehist.py]
  This exercise relies on the \texttt{readscores.py} and
\texttt{actsat.txt} files from the File I/O lab. You may also rewrite
that code using the CSV module.

  Write a program that generates a histogram of average ACT scores.
  For example:

  \begin{center}
  \includegraphics[width=0.8\textwidth]{img/actsat_hist.png}
  \end{center}
\end{ex}

\begin{ex}[scorebar.py]
  This exercise relies on the \texttt{readscores.py} and
\texttt{actsat.txt} files from the File I/O lab. You may also rewrite
that code using the CSV module.

  Write a program that draw the following charts.
  \begin{enumerate}
    \item A bar chart where each state/territory is represented by two
      bars, one for the composite ACT score and the other for the total
      score of all 3 SAT tests.

      Each SAT section is out of 800 points, while the ACT is out of
      36 points. Each bar should have the same maximum heights, but the
      labels should have the correct SAT or ACT score. See the example
      image.
    \item Produce the same chart as in part 2, but only for states in which
      less than 50\% take the ACT and more than 50\% take the SAT. (There
      should be 21 states/territories like this.)
  \end{enumerate}

  \textsl{Hint:} Notice the scale is different for each plot. One way of 
    adjusting the scales is to divide each number in the data so that
    every number is between 0 and 1. For the SAT scores, a score of 0 would be 0
    and a score of 2400 would be 1.0. Then assign the label ``0'' to 0, and
    the label ``1800'' to 0.5, and the label ``2400'' to 1.0.
    Similarly, -1 would have label ``36''.
    
    This is an example of the first bar plot:
  \begin{center}
  \includegraphics[width=\textwidth]{img/actsat_bars_all.png}
  \end{center}
\end{ex}

\begin{infobox}{Note}
None of these plot have to be exactly the same as the examples, they need only convey the same information in an understandable plot.
\end{infobox}

\section{The CSV Module}
CSV files are used to store tabular data. They have comma separated values on
each line. Most spreadhseet programs support CSV output and input. Python comes
with the CSV module for reading and writing such files. It supports any
delimiter so you can also manage space-separated and tab-separated data. To
use the module, create a CSV reader using the filename of the data file. For
example, suppose we have the file \texttt{short.csv}. It has column labels
on the first row and columns are separated by commas.

\begin{verbatimcode}
Entity,x         ,y,  z
Fruit tree,1,2,3
Bats, 1, 3, 10
\end{verbatimcode}

We can use the \pythoninline{csv.DictReader} function to parse this data.
It takes an open file as the first argument and returns something that you
can use a for-loop to traverse. It essentially returns a list of dictionaries.
For example,

\begin{pyconcode}
>>> import csv
>>> with open('short.csv') as f:
...     l = [e for e in csv.DictReader(f)]
>>> print(l)
[{'Entity': 'Fruit tree', 'x': '1', 'y': '2', 'z': '3'},
 {'Entity': 'Bats', 'x': ' 1', 'y': ' 3', 'z': ' 10'}]
\end{pyconcode}

Read the documentation to learn about writing CSV files and the
\pythoninline{csv.Sniffer}, which can be used to deduce the format of
a CSV file.

\begin{center}
\url{https://docs.python.org/3/library/csv.html}
\end{center}

The data from \url{http://www.gapminder.org/data/} was converted to CSV and
parsed using Python's CSV module to form the file \texttt{country\_data.py}. 

\begin{infobox}{Extra Credit (10 Points)}
Use matplotlib to draw scatter plots relating worldwide life expectancy,
income per person, and population for the years 2010 and 1960.

You may access the data by completing the extra credit or by importing
\texttt{country\_data.py}. The data is stored in the \pythoninline{data1960}
and \pythoninline{data2010} variables and looks like:

\begin{python3code}
data1960 = [{'country': 'Andorra',
    'expectancy': None,
    'gdp': 15234.0,
    'population': 13414.0},
   {'country': 'Eritrea',
    'expectancy': 41.8278,
    'gdp': 885.0,
    'population': 1407631.0}, ...
\end{python3code}

See ``200 Years, 200 Countries'' by Hans Rosling if you want a
good presentation on this data.

Notice the special value \pythoninline{None} is present.
To check if a variable \pythoninline{x} is \pythoninline{None},
type \pythoninline{x == None} or \pythoninline{x is None}.


You are required to:

\begin{enumerate}
\item Draw a scatter plot with x and y coordinates set to income and life
expectancy. If there is a \pythoninline{None} value, replace it with the
minimum income or the minimum life expectancy or an area set to zero.

\item The area of each data point should be related to the population of every
country. You can choose how to scale the data, but to make it look like the
example, you may use:

\begin{python3code}
scaled_pop = [800 * p / max(pop) for p in pop]
\end{python3code}

\item The scatter plots must be labeled and titled. X label: ``Income'', y
label: ``Life expectancy'', title: ``Year (year of data)''.

\item Annotate China, Russia, United States, and Afghanistan as shown.
Annotation text should be drawn away from the annotation coordinates.
You can get an arrow like in the example with this keyword argument:

\begin{python3code}
arrowprops={'arrowstyle': 'wedge,tail_width=0.25', 'color': 'black'}
\end{python3code}

\item Draw dashed red lines at the mean and at the max life expectancy.
Python's max function is useful for this.
\end{enumerate}

Here is the plot for the 2010 and 1960 data:

\begin{center}
\includegraphics[width=\textwidth]{img/scatter_2010.png}
\end{center}
\end{infobox}

\begin{infobox}{Supplementary Files}
The \texttt{country\_data.py} file is available on canvas.
\end{infobox}


\printindex

\input{submitting}

\end{document}
