Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Michy01/1ecd7807cf4df61357ff846c3c38586c to your computer and use it in GitHub Desktop.
Save Michy01/1ecd7807cf4df61357ff846c3c38586c to your computer and use it in GitHub Desktop.
Created on Skills Network Labs
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"<a href=\"https://cognitiveclass.ai\"><img src = \"https://ibm.box.com/shared/static/9gegpsmnsoo25ikkbl4qzlvlyjbgxs5x.png\" width = 400> </a>\n",
"\n",
"<h1 align=center><font size = 5>Pie Charts, Box Plots, Scatter Plots, and Bubble Plots</font></h1>"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"## Introduction\n",
"\n",
"In this lab session, we continue exploring the Matplotlib library. More specificatlly, we will learn how to create pie charts, box plots, scatter plots, and bubble charts."
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"## Table of Contents\n",
"\n",
"<div class=\"alert alert-block alert-info\" style=\"margin-top: 20px\">\n",
"\n",
"1. [Exploring Datasets with *p*andas](#0)<br>\n",
"2. [Downloading and Prepping Data](#2)<br>\n",
"3. [Visualizing Data using Matplotlib](#4) <br>\n",
"4. [Pie Charts](#6) <br>\n",
"5. [Box Plots](#8) <br>\n",
"6. [Scatter Plots](#10) <br>\n",
"7. [Bubble Plots](#12) <br> \n",
"</div>\n",
"<hr>"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"# Exploring Datasets with *pandas* and Matplotlib<a id=\"0\"></a>\n",
"\n",
"Toolkits: The course heavily relies on [*pandas*](http://pandas.pydata.org/) and [**Numpy**](http://www.numpy.org/) for data wrangling, analysis, and visualization. The primary plotting library we will explore in the course is [Matplotlib](http://matplotlib.org/).\n",
"\n",
"Dataset: Immigration to Canada from 1980 to 2013 - [International migration flows to and from selected countries - The 2015 revision](http://www.un.org/en/development/desa/population/migration/data/empirical2/migrationflows.shtml) from United Nation's website.\n",
"\n",
"The dataset contains annual data on the flows of international migrants as recorded by the countries of destination. The data presents both inflows and outflows according to the place of birth, citizenship or place of previous / next residence both for foreigners and nationals. In this lab, we will focus on the Canadian Immigration data."
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"# Downloading and Prepping Data <a id=\"2\"></a>"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Import primary modules."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"editable": true,
"jupyter": {
"outputs_hidden": false
},
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [],
"source": [
"import numpy as np # useful for many scientific computing in Python\n",
"import pandas as pd # primary data structure library"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Let's download and import our primary Canadian Immigration dataset using *pandas* `read_excel()` method. Normally, before we can do that, we would need to download a module which *pandas* requires to read in excel files. This module is **xlrd**. For your convenience, we have pre-installed this module, so you would not have to worry about that. Otherwise, you would need to run the following line of code to install the **xlrd** module:\n",
"```\n",
"!conda install -c anaconda xlrd --yes\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Download the dataset and read it into a *pandas* dataframe."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"editable": true,
"jupyter": {
"outputs_hidden": false
},
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Data downloaded and read into a dataframe!\n"
]
}
],
"source": [
"df_can = pd.read_excel('https://s3-api.us-geo.objectstorage.softlayer.net/cf-courses-data/CognitiveClass/DV0101EN/labs/Data_Files/Canada.xlsx',\n",
" sheet_name='Canada by Citizenship',\n",
" skiprows=range(20),\n",
" skipfooter=2\n",
" )\n",
"\n",
"print('Data downloaded and read into a dataframe!')"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Let's take a look at the first five items in our dataset."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"editable": true,
"jupyter": {
"outputs_hidden": false
},
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Type</th>\n",
" <th>Coverage</th>\n",
" <th>OdName</th>\n",
" <th>AREA</th>\n",
" <th>AreaName</th>\n",
" <th>REG</th>\n",
" <th>RegName</th>\n",
" <th>DEV</th>\n",
" <th>DevName</th>\n",
" <th>1980</th>\n",
" <th>...</th>\n",
" <th>2004</th>\n",
" <th>2005</th>\n",
" <th>2006</th>\n",
" <th>2007</th>\n",
" <th>2008</th>\n",
" <th>2009</th>\n",
" <th>2010</th>\n",
" <th>2011</th>\n",
" <th>2012</th>\n",
" <th>2013</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Immigrants</td>\n",
" <td>Foreigners</td>\n",
" <td>Afghanistan</td>\n",
" <td>935</td>\n",
" <td>Asia</td>\n",
" <td>5501</td>\n",
" <td>Southern Asia</td>\n",
" <td>902</td>\n",
" <td>Developing regions</td>\n",
" <td>16</td>\n",
" <td>...</td>\n",
" <td>2978</td>\n",
" <td>3436</td>\n",
" <td>3009</td>\n",
" <td>2652</td>\n",
" <td>2111</td>\n",
" <td>1746</td>\n",
" <td>1758</td>\n",
" <td>2203</td>\n",
" <td>2635</td>\n",
" <td>2004</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>Immigrants</td>\n",
" <td>Foreigners</td>\n",
" <td>Albania</td>\n",
" <td>908</td>\n",
" <td>Europe</td>\n",
" <td>925</td>\n",
" <td>Southern Europe</td>\n",
" <td>901</td>\n",
" <td>Developed regions</td>\n",
" <td>1</td>\n",
" <td>...</td>\n",
" <td>1450</td>\n",
" <td>1223</td>\n",
" <td>856</td>\n",
" <td>702</td>\n",
" <td>560</td>\n",
" <td>716</td>\n",
" <td>561</td>\n",
" <td>539</td>\n",
" <td>620</td>\n",
" <td>603</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>Immigrants</td>\n",
" <td>Foreigners</td>\n",
" <td>Algeria</td>\n",
" <td>903</td>\n",
" <td>Africa</td>\n",
" <td>912</td>\n",
" <td>Northern Africa</td>\n",
" <td>902</td>\n",
" <td>Developing regions</td>\n",
" <td>80</td>\n",
" <td>...</td>\n",
" <td>3616</td>\n",
" <td>3626</td>\n",
" <td>4807</td>\n",
" <td>3623</td>\n",
" <td>4005</td>\n",
" <td>5393</td>\n",
" <td>4752</td>\n",
" <td>4325</td>\n",
" <td>3774</td>\n",
" <td>4331</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>Immigrants</td>\n",
" <td>Foreigners</td>\n",
" <td>American Samoa</td>\n",
" <td>909</td>\n",
" <td>Oceania</td>\n",
" <td>957</td>\n",
" <td>Polynesia</td>\n",
" <td>902</td>\n",
" <td>Developing regions</td>\n",
" <td>0</td>\n",
" <td>...</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>Immigrants</td>\n",
" <td>Foreigners</td>\n",
" <td>Andorra</td>\n",
" <td>908</td>\n",
" <td>Europe</td>\n",
" <td>925</td>\n",
" <td>Southern Europe</td>\n",
" <td>901</td>\n",
" <td>Developed regions</td>\n",
" <td>0</td>\n",
" <td>...</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>5 rows × 43 columns</p>\n",
"</div>"
],
"text/plain": [
" Type Coverage OdName AREA AreaName REG \\\n",
"0 Immigrants Foreigners Afghanistan 935 Asia 5501 \n",
"1 Immigrants Foreigners Albania 908 Europe 925 \n",
"2 Immigrants Foreigners Algeria 903 Africa 912 \n",
"3 Immigrants Foreigners American Samoa 909 Oceania 957 \n",
"4 Immigrants Foreigners Andorra 908 Europe 925 \n",
"\n",
" RegName DEV DevName 1980 ... 2004 2005 2006 \\\n",
"0 Southern Asia 902 Developing regions 16 ... 2978 3436 3009 \n",
"1 Southern Europe 901 Developed regions 1 ... 1450 1223 856 \n",
"2 Northern Africa 902 Developing regions 80 ... 3616 3626 4807 \n",
"3 Polynesia 902 Developing regions 0 ... 0 0 1 \n",
"4 Southern Europe 901 Developed regions 0 ... 0 0 1 \n",
"\n",
" 2007 2008 2009 2010 2011 2012 2013 \n",
"0 2652 2111 1746 1758 2203 2635 2004 \n",
"1 702 560 716 561 539 620 603 \n",
"2 3623 4005 5393 4752 4325 3774 4331 \n",
"3 0 0 0 0 0 0 0 \n",
"4 1 0 0 0 0 1 1 \n",
"\n",
"[5 rows x 43 columns]"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_can.head()"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Let's find out how many entries there are in our dataset."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"editable": true,
"jupyter": {
"outputs_hidden": false
},
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(195, 43)\n"
]
}
],
"source": [
"# print the dimensions of the dataframe\n",
"print(df_can.shape)"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Clean up data. We will make some modifications to the original dataset to make it easier to create our visualizations. Refer to *Introduction to Matplotlib and Line Plots* and *Area Plots, Histograms, and Bar Plots* for a detailed description of this preprocessing."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"editable": true,
"jupyter": {
"outputs_hidden": false
},
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"data dimensions: (195, 38)\n"
]
}
],
"source": [
"# clean up the dataset to remove unnecessary columns (eg. REG) \n",
"df_can.drop(['AREA', 'REG', 'DEV', 'Type', 'Coverage'], axis=1, inplace=True)\n",
"\n",
"# let's rename the columns so that they make sense\n",
"df_can.rename(columns={'OdName':'Country', 'AreaName':'Continent','RegName':'Region'}, inplace=True)\n",
"\n",
"# for sake of consistency, let's also make all column labels of type string\n",
"df_can.columns = list(map(str, df_can.columns))\n",
"\n",
"# set the country name as index - useful for quickly looking up countries using .loc method\n",
"df_can.set_index('Country', inplace=True)\n",
"\n",
"# add total column\n",
"df_can['Total'] = df_can.sum(axis=1)\n",
"\n",
"# years that we will be using in this lesson - useful for plotting later on\n",
"years = list(map(str, range(1980, 2014)))\n",
"print('data dimensions:', df_can.shape)"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"# Visualizing Data using Matplotlib<a id=\"4\"></a>"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Import `Matplotlib`."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"editable": true,
"jupyter": {
"outputs_hidden": false
},
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Matplotlib version: 3.1.1\n"
]
}
],
"source": [
"%matplotlib inline\n",
"\n",
"import matplotlib as mpl\n",
"import matplotlib.pyplot as plt\n",
"\n",
"mpl.style.use('ggplot') # optional: for ggplot-like style\n",
"\n",
"# check for latest version of Matplotlib\n",
"print('Matplotlib version: ', mpl.__version__) # >= 2.0.0"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"# Pie Charts <a id=\"6\"></a>\n",
"\n",
"A `pie chart` is a circualr graphic that displays numeric proportions by dividing a circle (or pie) into proportional slices. You are most likely already familiar with pie charts as it is widely used in business and media. We can create pie charts in Matplotlib by passing in the `kind=pie` keyword.\n",
"\n",
"Let's use a pie chart to explore the proportion (percentage) of new immigrants grouped by continents for the entire time period from 1980 to 2013. "
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Step 1: Gather data. \n",
"\n",
"We will use *pandas* `groupby` method to summarize the immigration data by `Continent`. The general process of `groupby` involves the following steps:\n",
"\n",
"1. **Split:** Splitting the data into groups based on some criteria.\n",
"2. **Apply:** Applying a function to each group independently:\n",
" .sum()\n",
" .count()\n",
" .mean() \n",
" .std() \n",
" .aggregate()\n",
" .apply()\n",
" .etc..\n",
"3. **Combine:** Combining the results into a data structure."
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"<img src=\"https://s3-api.us-geo.objectstorage.softlayer.net/cf-courses-data/CognitiveClass/DV0101EN/labs/Images/Mod3Fig4SplitApplyCombine.png\" height=400 align=\"center\">"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"editable": true,
"jupyter": {
"outputs_hidden": false
},
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"<class 'pandas.core.groupby.generic.DataFrameGroupBy'>\n"
]
},
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>1980</th>\n",
" <th>1981</th>\n",
" <th>1982</th>\n",
" <th>1983</th>\n",
" <th>1984</th>\n",
" <th>1985</th>\n",
" <th>1986</th>\n",
" <th>1987</th>\n",
" <th>1988</th>\n",
" <th>1989</th>\n",
" <th>...</th>\n",
" <th>2005</th>\n",
" <th>2006</th>\n",
" <th>2007</th>\n",
" <th>2008</th>\n",
" <th>2009</th>\n",
" <th>2010</th>\n",
" <th>2011</th>\n",
" <th>2012</th>\n",
" <th>2013</th>\n",
" <th>Total</th>\n",
" </tr>\n",
" <tr>\n",
" <th>Continent</th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>Africa</th>\n",
" <td>3951</td>\n",
" <td>4363</td>\n",
" <td>3819</td>\n",
" <td>2671</td>\n",
" <td>2639</td>\n",
" <td>2650</td>\n",
" <td>3782</td>\n",
" <td>7494</td>\n",
" <td>7552</td>\n",
" <td>9894</td>\n",
" <td>...</td>\n",
" <td>27523</td>\n",
" <td>29188</td>\n",
" <td>28284</td>\n",
" <td>29890</td>\n",
" <td>34534</td>\n",
" <td>40892</td>\n",
" <td>35441</td>\n",
" <td>38083</td>\n",
" <td>38543</td>\n",
" <td>618948</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Asia</th>\n",
" <td>31025</td>\n",
" <td>34314</td>\n",
" <td>30214</td>\n",
" <td>24696</td>\n",
" <td>27274</td>\n",
" <td>23850</td>\n",
" <td>28739</td>\n",
" <td>43203</td>\n",
" <td>47454</td>\n",
" <td>60256</td>\n",
" <td>...</td>\n",
" <td>159253</td>\n",
" <td>149054</td>\n",
" <td>133459</td>\n",
" <td>139894</td>\n",
" <td>141434</td>\n",
" <td>163845</td>\n",
" <td>146894</td>\n",
" <td>152218</td>\n",
" <td>155075</td>\n",
" <td>3317794</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Europe</th>\n",
" <td>39760</td>\n",
" <td>44802</td>\n",
" <td>42720</td>\n",
" <td>24638</td>\n",
" <td>22287</td>\n",
" <td>20844</td>\n",
" <td>24370</td>\n",
" <td>46698</td>\n",
" <td>54726</td>\n",
" <td>60893</td>\n",
" <td>...</td>\n",
" <td>35955</td>\n",
" <td>33053</td>\n",
" <td>33495</td>\n",
" <td>34692</td>\n",
" <td>35078</td>\n",
" <td>33425</td>\n",
" <td>26778</td>\n",
" <td>29177</td>\n",
" <td>28691</td>\n",
" <td>1410947</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Latin America and the Caribbean</th>\n",
" <td>13081</td>\n",
" <td>15215</td>\n",
" <td>16769</td>\n",
" <td>15427</td>\n",
" <td>13678</td>\n",
" <td>15171</td>\n",
" <td>21179</td>\n",
" <td>28471</td>\n",
" <td>21924</td>\n",
" <td>25060</td>\n",
" <td>...</td>\n",
" <td>24747</td>\n",
" <td>24676</td>\n",
" <td>26011</td>\n",
" <td>26547</td>\n",
" <td>26867</td>\n",
" <td>28818</td>\n",
" <td>27856</td>\n",
" <td>27173</td>\n",
" <td>24950</td>\n",
" <td>765148</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Northern America</th>\n",
" <td>9378</td>\n",
" <td>10030</td>\n",
" <td>9074</td>\n",
" <td>7100</td>\n",
" <td>6661</td>\n",
" <td>6543</td>\n",
" <td>7074</td>\n",
" <td>7705</td>\n",
" <td>6469</td>\n",
" <td>6790</td>\n",
" <td>...</td>\n",
" <td>8394</td>\n",
" <td>9613</td>\n",
" <td>9463</td>\n",
" <td>10190</td>\n",
" <td>8995</td>\n",
" <td>8142</td>\n",
" <td>7677</td>\n",
" <td>7892</td>\n",
" <td>8503</td>\n",
" <td>241142</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>5 rows × 35 columns</p>\n",
"</div>"
],
"text/plain": [
" 1980 1981 1982 1983 1984 1985 \\\n",
"Continent \n",
"Africa 3951 4363 3819 2671 2639 2650 \n",
"Asia 31025 34314 30214 24696 27274 23850 \n",
"Europe 39760 44802 42720 24638 22287 20844 \n",
"Latin America and the Caribbean 13081 15215 16769 15427 13678 15171 \n",
"Northern America 9378 10030 9074 7100 6661 6543 \n",
"\n",
" 1986 1987 1988 1989 ... 2005 \\\n",
"Continent ... \n",
"Africa 3782 7494 7552 9894 ... 27523 \n",
"Asia 28739 43203 47454 60256 ... 159253 \n",
"Europe 24370 46698 54726 60893 ... 35955 \n",
"Latin America and the Caribbean 21179 28471 21924 25060 ... 24747 \n",
"Northern America 7074 7705 6469 6790 ... 8394 \n",
"\n",
" 2006 2007 2008 2009 2010 \\\n",
"Continent \n",
"Africa 29188 28284 29890 34534 40892 \n",
"Asia 149054 133459 139894 141434 163845 \n",
"Europe 33053 33495 34692 35078 33425 \n",
"Latin America and the Caribbean 24676 26011 26547 26867 28818 \n",
"Northern America 9613 9463 10190 8995 8142 \n",
"\n",
" 2011 2012 2013 Total \n",
"Continent \n",
"Africa 35441 38083 38543 618948 \n",
"Asia 146894 152218 155075 3317794 \n",
"Europe 26778 29177 28691 1410947 \n",
"Latin America and the Caribbean 27856 27173 24950 765148 \n",
"Northern America 7677 7892 8503 241142 \n",
"\n",
"[5 rows x 35 columns]"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# group countries by continents and apply sum() function \n",
"df_continents = df_can.groupby('Continent', axis=0).sum()\n",
"\n",
"# note: the output of the groupby method is a `groupby' object. \n",
"# we can not use it further until we apply a function (eg .sum())\n",
"print(type(df_can.groupby('Continent', axis=0)))\n",
"\n",
"df_continents.head()"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Step 2: Plot the data. We will pass in `kind = 'pie'` keyword, along with the following additional parameters:\n",
"- `autopct` - is a string or function used to label the wedges with their numeric value. The label will be placed inside the wedge. If it is a format string, the label will be `fmt%pct`.\n",
"- `startangle` - rotates the start of the pie chart by angle degrees counterclockwise from the x-axis.\n",
"- `shadow` - Draws a shadow beneath the pie (to give a 3D feel)."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"editable": true,
"jupyter": {
"outputs_hidden": false
},
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 360x432 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# autopct create %, start angle represent starting point\n",
"df_continents['Total'].plot(kind='pie',\n",
" figsize=(5, 6),\n",
" autopct='%1.1f%%', # add in percentages\n",
" startangle=90, # start angle 90° (Africa)\n",
" shadow=True, # add shadow \n",
" )\n",
"\n",
"plt.title('Immigration to Canada by Continent [1980 - 2013]')\n",
"plt.axis('equal') # Sets the pie chart to look like a circle.\n",
"\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"The above visual is not very clear, the numbers and text overlap in some instances. Let's make a few modifications to improve the visuals:\n",
"\n",
"* Remove the text labels on the pie chart by passing in `legend` and add it as a seperate legend using `plt.legend()`.\n",
"* Push out the percentages to sit just outside the pie chart by passing in `pctdistance` parameter.\n",
"* Pass in a custom set of colors for continents by passing in `colors` parameter.\n",
"* **Explode** the pie chart to emphasize the lowest three continents (Africa, North America, and Latin America and Carribbean) by pasing in `explode` parameter.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"jupyter": {
"outputs_hidden": false
},
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [],
"source": [
"colors_list = ['gold', 'yellowgreen', 'lightcoral', 'lightskyblue', 'lightgreen', 'pink']\n",
"explode_list = [0.1, 0, 0, 0, 0.1, 0.1] # ratio for each continent with which to offset each wedge.\n",
"\n",
"df_continents['Total'].plot(kind='pie',\n",
" figsize=(15, 6),\n",
" autopct='%1.1f%%', \n",
" startangle=90, \n",
" shadow=True, \n",
" labels=None, # turn off labels on pie chart\n",
" pctdistance=1.12, # the ratio between the center of each pie slice and the start of the text generated by autopct \n",
" colors=colors_list, # add custom colors\n",
" explode=explode_list # 'explode' lowest 3 continents\n",
" )\n",
"\n",
"# scale the title up by 12% to match pctdistance\n",
"plt.title('Immigration to Canada by Continent [1980 - 2013]', y=1.12) \n",
"\n",
"plt.axis('equal') \n",
"\n",
"# add legend\n",
"plt.legend(labels=df_continents.index, loc='upper left') \n",
"\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"**Question:** Using a pie chart, explore the proportion (percentage) of new immigrants grouped by continents in the year 2013.\n",
"\n",
"**Note**: You might need to play with the explore values in order to fix any overlapping slice values."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"jupyter": {
"outputs_hidden": false
},
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [],
"source": [
"### type your answer here\n",
"\n",
"\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Double-click __here__ for the solution.\n",
"<!-- The correct answer is:\n",
"explode_list = [0.1, 0, 0, 0, 0.1, 0.2] # ratio for each continent with which to offset each wedge.\n",
"-->\n",
"\n",
"<!--\n",
"df_continents['2013'].plot(kind='pie',\n",
" figsize=(15, 6),\n",
" autopct='%1.1f%%', \n",
" startangle=90, \n",
" shadow=True, \n",
" labels=None, # turn off labels on pie chart\n",
" pctdistance=1.12, # the ratio between the pie center and start of text label\n",
" explode=explode_list # 'explode' lowest 3 continents\n",
" )\n",
"-->\n",
"\n",
"<!--\n",
"\\\\ # scale the title up by 12% to match pctdistance\n",
"plt.title('Immigration to Canada by Continent in 2013', y=1.12) \n",
"plt.axis('equal') \n",
"-->\n",
"\n",
"<!--\n",
"\\\\ # add legend\n",
"plt.legend(labels=df_continents.index, loc='upper left') \n",
"-->\n",
"\n",
"<!--\n",
"\\\\ # show plot\n",
"plt.show()\n",
"-->"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"# Box Plots <a id=\"8\"></a>\n",
"\n",
"A `box plot` is a way of statistically representing the *distribution* of the data through five main dimensions: \n",
"\n",
"- **Minimun:** Smallest number in the dataset.\n",
"- **First quartile:** Middle number between the `minimum` and the `median`.\n",
"- **Second quartile (Median):** Middle number of the (sorted) dataset.\n",
"- **Third quartile:** Middle number between `median` and `maximum`.\n",
"- **Maximum:** Highest number in the dataset."
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"<img src=\"https://s3-api.us-geo.objectstorage.softlayer.net/cf-courses-data/CognitiveClass/DV0101EN/labs/Images/boxplot_complete.png\" width=440, align=\"center\">"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"To make a `box plot`, we can use `kind=box` in `plot` method invoked on a *pandas* series or dataframe.\n",
"\n",
"Let's plot the box plot for the Japanese immigrants between 1980 - 2013."
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Step 1: Get the dataset. Even though we are extracting the data for just one country, we will obtain it as a dataframe. This will help us with calling the `dataframe.describe()` method to view the percentiles."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"editable": true,
"jupyter": {
"outputs_hidden": false
},
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [],
"source": [
"# to get a dataframe, place extra square brackets around 'Japan'.\n",
"df_japan = df_can.loc[['Japan'], years].transpose()\n",
"df_japan.head()"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Step 2: Plot by passing in `kind='box'`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"editable": true,
"jupyter": {
"outputs_hidden": false
},
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [],
"source": [
"df_japan.plot(kind='box', figsize=(8, 6))\n",
"\n",
"plt.title('Box plot of Japanese Immigrants from 1980 - 2013')\n",
"plt.ylabel('Number of Immigrants')\n",
"\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"We can immediately make a few key observations from the plot above:\n",
"1. The minimum number of immigrants is around 200 (min), maximum number is around 1300 (max), and median number of immigrants is around 900 (median).\n",
"2. 25% of the years for period 1980 - 2013 had an annual immigrant count of ~500 or fewer (First quartile).\n",
"2. 75% of the years for period 1980 - 2013 had an annual immigrant count of ~1100 or fewer (Third quartile).\n",
"\n",
"We can view the actual numbers by calling the `describe()` method on the dataframe."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"editable": true,
"jupyter": {
"outputs_hidden": false
},
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [],
"source": [
"df_japan.describe()"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"One of the key benefits of box plots is comparing the distribution of multiple datasets. In one of the previous labs, we observed that China and India had very similar immigration trends. Let's analyize these two countries further using box plots.\n",
"\n",
"**Question:** Compare the distribution of the number of new immigrants from India and China for the period 1980 - 2013."
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Step 1: Get the dataset for China and India and call the dataframe **df_CI**."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"jupyter": {
"outputs_hidden": false
},
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [],
"source": [
"### type your answer here\n",
"\n",
"\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Double-click __here__ for the solution.\n",
"<!-- The correct answer is:\n",
"df_CI= df_can.loc[['China', 'India'], years].transpose()\n",
"df_CI.head()\n",
"-->"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Let's view the percentages associated with both countries using the `describe()` method."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"jupyter": {
"outputs_hidden": false
},
"new_sheet": false,
"run_control": {
"read_only": false
},
"scrolled": true
},
"outputs": [],
"source": [
"### type your answer here\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Double-click __here__ for the solution.\n",
"<!-- The correct answer is:\n",
"df_CI.describe()\n",
"-->"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Step 2: Plot data."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"jupyter": {
"outputs_hidden": false
},
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [],
"source": [
"### type your answer here\n",
"\n",
"\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Double-click __here__ for the solution.\n",
"<!-- The correct answer is:\n",
"df_CI.plot(kind='box', figsize=(10, 7))\n",
"-->\n",
"\n",
"<!--\n",
"plt.title('Box plots of Immigrants from China and India (1980 - 2013)')\n",
"plt.xlabel('Number of Immigrants')\n",
"-->\n",
"\n",
"<!--\n",
"plt.show()\n",
"-->"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"We can observe that, while both countries have around the same median immigrant population (~20,000), China's immigrant population range is more spread out than India's. The maximum population from India for any year (36,210) is around 15% lower than the maximum population from China (42,584).\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"If you prefer to create horizontal box plots, you can pass the `vert` parameter in the **plot** function and assign it to *False*. You can also specify a different color in case you are not a big fan of the default red color."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"jupyter": {
"outputs_hidden": false
},
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [],
"source": [
"# horizontal box plots\n",
"df_CI.plot(kind='box', figsize=(10, 7), color='blue', vert=False)\n",
"\n",
"plt.title('Box plots of Immigrants from China and India (1980 - 2013)')\n",
"plt.xlabel('Number of Immigrants')\n",
"\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"**Subplots**\n",
"\n",
"Often times we might want to plot multiple plots within the same figure. For example, we might want to perform a side by side comparison of the box plot with the line plot of China and India's immigration.\n",
"\n",
"To visualize multiple plots together, we can create a **`figure`** (overall canvas) and divide it into **`subplots`**, each containing a plot. With **subplots**, we usually work with the **artist layer** instead of the **scripting layer**. \n",
"\n",
"Typical syntax is : <br>\n",
"```python\n",
" fig = plt.figure() # create figure\n",
" ax = fig.add_subplot(nrows, ncols, plot_number) # create subplots\n",
"```\n",
"Where\n",
"- `nrows` and `ncols` are used to notionally split the figure into (`nrows` \\* `ncols`) sub-axes, \n",
"- `plot_number` is used to identify the particular subplot that this function is to create within the notional grid. `plot_number` starts at 1, increments across rows first and has a maximum of `nrows` * `ncols` as shown below.\n",
"\n",
"<img src=\"https://s3-api.us-geo.objectstorage.softlayer.net/cf-courses-data/CognitiveClass/DV0101EN/labs/Images/Mod3Fig5Subplots_V2.png\" width=500 align=\"center\">"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"We can then specify which subplot to place each plot by passing in the `ax` paramemter in `plot()` method as follows:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"editable": true,
"jupyter": {
"outputs_hidden": false
},
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [],
"source": [
"fig = plt.figure() # create figure\n",
"\n",
"ax0 = fig.add_subplot(1, 2, 1) # add subplot 1 (1 row, 2 columns, first plot)\n",
"ax1 = fig.add_subplot(1, 2, 2) # add subplot 2 (1 row, 2 columns, second plot). See tip below**\n",
"\n",
"# Subplot 1: Box plot\n",
"df_CI.plot(kind='box', color='blue', vert=False, figsize=(20, 6), ax=ax0) # add to subplot 1\n",
"ax0.set_title('Box Plots of Immigrants from China and India (1980 - 2013)')\n",
"ax0.set_xlabel('Number of Immigrants')\n",
"ax0.set_ylabel('Countries')\n",
"\n",
"# Subplot 2: Line plot\n",
"df_CI.plot(kind='line', figsize=(20, 6), ax=ax1) # add to subplot 2\n",
"ax1.set_title ('Line Plots of Immigrants from China and India (1980 - 2013)')\n",
"ax1.set_ylabel('Number of Immigrants')\n",
"ax1.set_xlabel('Years')\n",
"\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"** * Tip regarding subplot convention **\n",
"\n",
"In the case when `nrows`, `ncols`, and `plot_number` are all less than 10, a convenience exists such that the a 3 digit number can be given instead, where the hundreds represent `nrows`, the tens represent `ncols` and the units represent `plot_number`. For instance,\n",
"```python\n",
" subplot(211) == subplot(2, 1, 1) \n",
"```\n",
"produces a subaxes in a figure which represents the top plot (i.e. the first) in a 2 rows by 1 column notional grid (no grid actually exists, but conceptually this is how the returned subplot has been positioned)."
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Let's try something a little more advanced. \n",
"\n",
"Previously we identified the top 15 countries based on total immigration from 1980 - 2013.\n",
"\n",
"**Question:** Create a box plot to visualize the distribution of the top 15 countries (based on total immigration) grouped by the *decades* `1980s`, `1990s`, and `2000s`."
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Step 1: Get the dataset. Get the top 15 countries based on Total immigrant population. Name the dataframe **df_top15**."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"editable": true,
"jupyter": {
"outputs_hidden": false
},
"new_sheet": false,
"run_control": {
"read_only": false
},
"scrolled": true
},
"outputs": [],
"source": [
"### type your answer here\n",
"\n",
"\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Double-click __here__ for the solution.\n",
"<!-- The correct answer is:\n",
"df_top15 = df_can.sort_values(['Total'], ascending=False, axis=0).head(15)\n",
"df_top15\n",
"-->"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Step 2: Create a new dataframe which contains the aggregate for each decade. One way to do that:\n",
" 1. Create a list of all years in decades 80's, 90's, and 00's.\n",
" 2. Slice the original dataframe df_can to create a series for each decade and sum across all years for each country.\n",
" 3. Merge the three series into a new data frame. Call your dataframe **new_df**."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"editable": true,
"jupyter": {
"outputs_hidden": false
},
"new_sheet": false,
"run_control": {
"read_only": false
},
"scrolled": true
},
"outputs": [],
"source": [
"### type your answer here\n",
"\n",
"\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Double-click __here__ for the solution.\n",
"<!-- The correct answer is:\n",
"\\\\ # create a list of all years in decades 80's, 90's, and 00's\n",
"years_80s = list(map(str, range(1980, 1990))) \n",
"years_90s = list(map(str, range(1990, 2000))) \n",
"years_00s = list(map(str, range(2000, 2010))) \n",
"-->\n",
"\n",
"<!--\n",
"\\\\ # slice the original dataframe df_can to create a series for each decade\n",
"df_80s = df_top15.loc[:, years_80s].sum(axis=1) \n",
"df_90s = df_top15.loc[:, years_90s].sum(axis=1) \n",
"df_00s = df_top15.loc[:, years_00s].sum(axis=1)\n",
"-->\n",
"\n",
"<!--\n",
"\\\\ # merge the three series into a new data frame\n",
"new_df = pd.DataFrame({'1980s': df_80s, '1990s': df_90s, '2000s':df_00s}) \n",
"-->\n",
"\n",
"<!--\n",
"\\\\ # display dataframe\n",
"new_df.head()\n",
"-->"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Let's learn more about the statistics associated with the dataframe using the `describe()` method."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"jupyter": {
"outputs_hidden": false
},
"new_sheet": false,
"run_control": {
"read_only": false
},
"scrolled": true
},
"outputs": [],
"source": [
"### type your answer here\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Double-click __here__ for the solution.\n",
"<!-- The correct answer is:\n",
"new_df.describe()\n",
"-->"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Step 3: Plot the box plots."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"editable": true,
"jupyter": {
"outputs_hidden": false
},
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [],
"source": [
"### type your answer here\n",
"\n",
"\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Double-click __here__ for the solution.\n",
"<!-- The correct answer is:\n",
"new_df.plot(kind='box', figsize=(10, 6))\n",
"-->\n",
"\n",
"<!--\n",
"plt.title('Immigration from top 15 countries for decades 80s, 90s and 2000s')\n",
"-->\n",
"\n",
"<!--\n",
"plt.show()\n",
"-->"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Note how the box plot differs from the summary table created. The box plot scans the data and identifies the outliers. In order to be an outlier, the data value must be:<br>\n",
"* larger than Q3 by at least 1.5 times the interquartile range (IQR), or,\n",
"* smaller than Q1 by at least 1.5 times the IQR.\n",
"\n",
"Let's look at decade 2000s as an example: <br>\n",
"* Q1 (25%) = 36,101.5 <br>\n",
"* Q3 (75%) = 105,505.5 <br>\n",
"* IQR = Q3 - Q1 = 69,404 <br>\n",
"\n",
"Using the definition of outlier, any value that is greater than Q3 by 1.5 times IQR will be flagged as outlier.\n",
"\n",
"Outlier > 105,505.5 + (1.5 * 69,404) <br>\n",
"Outlier > 209,611.5"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"editable": true,
"jupyter": {
"outputs_hidden": false
},
"new_sheet": false,
"run_control": {
"read_only": false
},
"scrolled": true
},
"outputs": [],
"source": [
"# let's check how many entries fall above the outlier threshold \n",
"new_df[new_df['2000s']> 209611.5]"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"China and India are both considered as outliers since their population for the decade exceeds 209,611.5. \n",
"\n",
"The box plot is an advanced visualizaiton tool, and there are many options and customizations that exceed the scope of this lab. Please refer to [Matplotlib documentation](http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.boxplot) on box plots for more information."
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"# Scatter Plots <a id=\"10\"></a>\n",
"\n",
"A `scatter plot` (2D) is a useful method of comparing variables against each other. `Scatter` plots look similar to `line plots` in that they both map independent and dependent variables on a 2D graph. While the datapoints are connected together by a line in a line plot, they are not connected in a scatter plot. The data in a scatter plot is considered to express a trend. With further analysis using tools like regression, we can mathematically calculate this relationship and use it to predict trends outside the dataset.\n",
"\n",
"Let's start by exploring the following:\n",
"\n",
"Using a `scatter plot`, let's visualize the trend of total immigrantion to Canada (all countries combined) for the years 1980 - 2013."
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Step 1: Get the dataset. Since we are expecting to use the relationship betewen `years` and `total population`, we will convert `years` to `int` type."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"editable": true,
"jupyter": {
"outputs_hidden": false
},
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [],
"source": [
"# we can use the sum() method to get the total population per year\n",
"df_tot = pd.DataFrame(df_can[years].sum(axis=0))\n",
"\n",
"# change the years to type int (useful for regression later on)\n",
"df_tot.index = map(int, df_tot.index)\n",
"\n",
"# reset the index to put in back in as a column in the df_tot dataframe\n",
"df_tot.reset_index(inplace = True)\n",
"\n",
"# rename columns\n",
"df_tot.columns = ['year', 'total']\n",
"\n",
"# view the final dataframe\n",
"df_tot.head()"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Step 2: Plot the data. In `Matplotlib`, we can create a `scatter` plot set by passing in `kind='scatter'` as plot argument. We will also need to pass in `x` and `y` keywords to specify the columns that go on the x- and the y-axis."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"editable": true,
"jupyter": {
"outputs_hidden": false
},
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [],
"source": [
"df_tot.plot(kind='scatter', x='year', y='total', figsize=(10, 6), color='darkblue')\n",
"\n",
"plt.title('Total Immigration to Canada from 1980 - 2013')\n",
"plt.xlabel('Year')\n",
"plt.ylabel('Number of Immigrants')\n",
"\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Notice how the scatter plot does not connect the datapoints together. We can clearly observe an upward trend in the data: as the years go by, the total number of immigrants increases. We can mathematically analyze this upward trend using a regression line (line of best fit). "
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"So let's try to plot a linear line of best fit, and use it to predict the number of immigrants in 2015.\n",
"\n",
"Step 1: Get the equation of line of best fit. We will use **Numpy**'s `polyfit()` method by passing in the following:\n",
"- `x`: x-coordinates of the data. \n",
"- `y`: y-coordinates of the data. \n",
"- `deg`: Degree of fitting polynomial. 1 = linear, 2 = quadratic, and so on."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"editable": true,
"jupyter": {
"outputs_hidden": false
},
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [],
"source": [
"x = df_tot['year'] # year on x-axis\n",
"y = df_tot['total'] # total on y-axis\n",
"fit = np.polyfit(x, y, deg=1)\n",
"\n",
"fit"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"The output is an array with the polynomial coefficients, highest powers first. Since we are plotting a linear regression `y= a*x + b`, our output has 2 elements `[5.56709228e+03, -1.09261952e+07]` with the the slope in position 0 and intercept in position 1. \n",
"\n",
"Step 2: Plot the regression line on the `scatter plot`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"editable": true,
"jupyter": {
"outputs_hidden": false
},
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [],
"source": [
"df_tot.plot(kind='scatter', x='year', y='total', figsize=(10, 6), color='darkblue')\n",
"\n",
"plt.title('Total Immigration to Canada from 1980 - 2013')\n",
"plt.xlabel('Year')\n",
"plt.ylabel('Number of Immigrants')\n",
"\n",
"# plot line of best fit\n",
"plt.plot(x, fit[0] * x + fit[1], color='red') # recall that x is the Years\n",
"plt.annotate('y={0:.0f} x + {1:.0f}'.format(fit[0], fit[1]), xy=(2000, 150000))\n",
"\n",
"plt.show()\n",
"\n",
"# print out the line of best fit\n",
"'No. Immigrants = {0:.0f} * Year + {1:.0f}'.format(fit[0], fit[1]) "
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Using the equation of line of best fit, we can estimate the number of immigrants in 2015:\n",
"```python\n",
"No. Immigrants = 5567 * Year - 10926195\n",
"No. Immigrants = 5567 * 2015 - 10926195\n",
"No. Immigrants = 291,310\n",
"```\n",
"When compared to the actuals from Citizenship and Immigration Canada's (CIC) [2016 Annual Report](http://www.cic.gc.ca/english/resources/publications/annual-report-2016/index.asp), we see that Canada accepted 271,845 immigrants in 2015. Our estimated value of 291,310 is within 7% of the actual number, which is pretty good considering our original data came from United Nations (and might differ slightly from CIC data).\n",
"\n",
"As a side note, we can observe that immigration took a dip around 1993 - 1997. Further analysis into the topic revealed that in 1993 Canada introcuded Bill C-86 which introduced revisions to the refugee determination system, mostly restrictive. Further amendments to the Immigration Regulations cancelled the sponsorship required for \"assisted relatives\" and reduced the points awarded to them, making it more difficult for family members (other than nuclear family) to immigrate to Canada. These restrictive measures had a direct impact on the immigration numbers for the next several years."
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"**Question**: Create a scatter plot of the total immigration from Denmark, Norway, and Sweden to Canada from 1980 to 2013?"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Step 1: Get the data:\n",
" 1. Create a dataframe the consists of the numbers associated with Denmark, Norway, and Sweden only. Name it **df_countries**.\n",
" 2. Sum the immigration numbers across all three countries for each year and turn the result into a dataframe. Name this new dataframe **df_total**.\n",
" 3. Reset the index in place.\n",
" 4. Rename the columns to **year** and **total**.\n",
" 5. Display the resulting dataframe."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"jupyter": {
"outputs_hidden": false
},
"new_sheet": false,
"run_control": {
"read_only": false
},
"scrolled": true
},
"outputs": [],
"source": [
"### type your answer here\n",
"\n",
"\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Double-click __here__ for the solution.\n",
"<!-- The correct answer is:\n",
"\\\\ # create df_countries dataframe\n",
"df_countries = df_can.loc[['Denmark', 'Norway', 'Sweden'], years].transpose()\n",
"-->\n",
"\n",
"<!--\n",
"\\\\ # create df_total by summing across three countries for each year\n",
"df_total = pd.DataFrame(df_countries.sum(axis=1))\n",
"-->\n",
"\n",
"<!--\n",
"\\\\ # reset index in place\n",
"df_total.reset_index(inplace=True)\n",
"-->\n",
"\n",
"<!--\n",
"\\\\ # rename columns\n",
"df_total.columns = ['year', 'total']\n",
"-->\n",
"\n",
"<!--\n",
"\\\\ # change column year from string to int to create scatter plot\n",
"df_total['year'] = df_total['year'].astype(int)\n",
"-->\n",
"\n",
"<!--\n",
"\\\\ # show resulting dataframe\n",
"df_total.head()\n",
"-->"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Step 2: Generate the scatter plot by plotting the total versus year in **df_total**."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"jupyter": {
"outputs_hidden": false
},
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [],
"source": [
"### type your answer here\n",
"\n",
"\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Double-click __here__ for the solution.\n",
"<!-- The correct answer is:\n",
"\\\\ # generate scatter plot\n",
"df_total.plot(kind='scatter', x='year', y='total', figsize=(10, 6), color='darkblue')\n",
"-->\n",
"\n",
"<!--\n",
"\\\\ # add title and label to axes\n",
"plt.title('Immigration from Denmark, Norway, and Sweden to Canada from 1980 - 2013')\n",
"plt.xlabel('Year')\n",
"plt.ylabel('Number of Immigrants')\n",
"-->\n",
"\n",
"<!--\n",
"\\\\ # show plot\n",
"plt.show()\n",
"-->"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"# Bubble Plots <a id=\"12\"></a>\n",
"\n",
"A `bubble plot` is a variation of the `scatter plot` that displays three dimensions of data (x, y, z). The datapoints are replaced with bubbles, and the size of the bubble is determined by the third variable 'z', also known as the weight. In `maplotlib`, we can pass in an array or scalar to the keyword `s` to `plot()`, that contains the weight of each point.\n",
"\n",
"**Let's start by analyzing the effect of Argentina's great depression**.\n",
"\n",
"Argentina suffered a great depression from 1998 - 2002, which caused widespread unemployment, riots, the fall of the government, and a default on the country's foreign debt. In terms of income, over 50% of Argentines were poor, and seven out of ten Argentine children were poor at the depth of the crisis in 2002. \n",
"\n",
"Let's analyze the effect of this crisis, and compare Argentina's immigration to that of it's neighbour Brazil. Let's do that using a `bubble plot` of immigration from Brazil and Argentina for the years 1980 - 2013. We will set the weights for the bubble as the *normalized* value of the population for each year."
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Step 1: Get the data for Brazil and Argentina. Like in the previous example, we will convert the `Years` to type int and bring it in the dataframe."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"editable": true,
"jupyter": {
"outputs_hidden": false
},
"new_sheet": false,
"run_control": {
"read_only": false
},
"scrolled": true
},
"outputs": [],
"source": [
"df_can_t = df_can[years].transpose() # transposed dataframe\n",
"\n",
"# cast the Years (the index) to type int\n",
"df_can_t.index = map(int, df_can_t.index)\n",
"\n",
"# let's label the index. This will automatically be the column name when we reset the index\n",
"df_can_t.index.name = 'Year'\n",
"\n",
"# reset index to bring the Year in as a column\n",
"df_can_t.reset_index(inplace=True)\n",
"\n",
"# view the changes\n",
"df_can_t.head()"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Step 2: Create the normalized weights. \n",
"\n",
"There are several methods of normalizations in statistics, each with its own use. In this case, we will use [feature scaling](https://en.wikipedia.org/wiki/Feature_scaling) to bring all values into the range [0,1]. The general formula is:\n",
"\n",
"<img src=\"https://s3-api.us-geo.objectstorage.softlayer.net/cf-courses-data/CognitiveClass/DV0101EN/labs/Images/Mod3Fig3FeatureScaling.png\" align=\"center\">\n",
"\n",
"where *`X`* is an original value, *`X'`* is the normalized value. The formula sets the max value in the dataset to 1, and sets the min value to 0. The rest of the datapoints are scaled to a value between 0-1 accordingly.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"editable": true,
"jupyter": {
"outputs_hidden": false
},
"new_sheet": false,
"run_control": {
"read_only": false
},
"scrolled": true
},
"outputs": [],
"source": [
"# normalize Brazil data\n",
"norm_brazil = (df_can_t['Brazil'] - df_can_t['Brazil'].min()) / (df_can_t['Brazil'].max() - df_can_t['Brazil'].min())\n",
"\n",
"# normalize Argentina data\n",
"norm_argentina = (df_can_t['Argentina'] - df_can_t['Argentina'].min()) / (df_can_t['Argentina'].max() - df_can_t['Argentina'].min())"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Step 3: Plot the data. \n",
"- To plot two different scatter plots in one plot, we can include the axes one plot into the other by passing it via the `ax` parameter. \n",
"- We will also pass in the weights using the `s` parameter. Given that the normalized weights are between 0-1, they won't be visible on the plot. Therefore we will:\n",
" - multiply weights by 2000 to scale it up on the graph, and,\n",
" - add 10 to compensate for the min value (which has a 0 weight and therefore scale with x2000)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"editable": true,
"jupyter": {
"outputs_hidden": false
},
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [],
"source": [
"# Brazil\n",
"ax0 = df_can_t.plot(kind='scatter',\n",
" x='Year',\n",
" y='Brazil',\n",
" figsize=(14, 8),\n",
" alpha=0.5, # transparency\n",
" color='green',\n",
" s=norm_brazil * 2000 + 10, # pass in weights \n",
" xlim=(1975, 2015)\n",
" )\n",
"\n",
"# Argentina\n",
"ax1 = df_can_t.plot(kind='scatter',\n",
" x='Year',\n",
" y='Argentina',\n",
" alpha=0.5,\n",
" color=\"blue\",\n",
" s=norm_argentina * 2000 + 10,\n",
" ax = ax0\n",
" )\n",
"\n",
"ax0.set_ylabel('Number of Immigrants')\n",
"ax0.set_title('Immigration from Brazil and Argentina from 1980 - 2013')\n",
"ax0.legend(['Brazil', 'Argentina'], loc='upper left', fontsize='x-large')"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"The size of the bubble corresponds to the magnitude of immigrating population for that year, compared to the 1980 - 2013 data. The larger the bubble, the more immigrants in that year.\n",
"\n",
"From the plot above, we can see a corresponding increase in immigration from Argentina during the 1998 - 2002 great depression. We can also observe a similar spike around 1985 to 1993. In fact, Argentina had suffered a great depression from 1974 - 1990, just before the onset of 1998 - 2002 great depression. \n",
"\n",
"On a similar note, Brazil suffered the *Samba Effect* where the Brazilian real (currency) dropped nearly 35% in 1999. There was a fear of a South American financial crisis as many South American countries were heavily dependent on industrial exports from Brazil. The Brazilian government subsequently adopted an austerity program, and the economy slowly recovered over the years, culminating in a surge in 2010. The immigration data reflect these events."
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"**Question**: Previously in this lab, we created box plots to compare immigration from China and India to Canada. Create bubble plots of immigration from China and India to visualize any differences with time from 1980 to 2013. You can use **df_can_t** that we defined and used in the previous example."
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Step 1: Normalize the data pertaining to China and India."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"button": false,
"collapsed": true,
"deletable": true,
"jupyter": {
"outputs_hidden": true
},
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [],
"source": [
"### type your answer here\n",
"\n",
"\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Double-click __here__ for the solution.\n",
"<!-- The correct answer is:\n",
"\\\\ # normalize China data\n",
"norm_china = (df_can_t['China'] - df_can_t['China'].min()) / (df_can_t['China'].max() - df_can_t['China'].min())\n",
"-->\n",
"\n",
"<!--\n",
"# normalize India data\n",
"norm_india = (df_can_t['India'] - df_can_t['India'].min()) / (df_can_t['India'].max() - df_can_t['India'].min())\n",
"-->"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Step 2: Generate the bubble plots."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"jupyter": {
"outputs_hidden": false
},
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [],
"source": [
"### type your answer here\n",
"\n",
"\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Double-click __here__ for the solution.\n",
"<!-- The correct answer is:\n",
"\\\\ # China\n",
"ax0 = df_can_t.plot(kind='scatter',\n",
" x='Year',\n",
" y='China',\n",
" figsize=(14, 8),\n",
" alpha=0.5, # transparency\n",
" color='green',\n",
" s=norm_china * 2000 + 10, # pass in weights \n",
" xlim=(1975, 2015)\n",
" )\n",
"-->\n",
"\n",
"<!--\n",
"\\\\ # India\n",
"ax1 = df_can_t.plot(kind='scatter',\n",
" x='Year',\n",
" y='India',\n",
" alpha=0.5,\n",
" color=\"blue\",\n",
" s=norm_india * 2000 + 10,\n",
" ax = ax0\n",
" )\n",
"-->\n",
"\n",
"<!--\n",
"ax0.set_ylabel('Number of Immigrants')\n",
"ax0.set_title('Immigration from China and India from 1980 - 2013')\n",
"ax0.legend(['China', 'India'], loc='upper left', fontsize='x-large')\n",
"-->"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"### Thank you for completing this lab!\n",
"\n",
"This notebook was created by [Jay Rajasekharan](https://www.linkedin.com/in/jayrajasekharan) with contributions from [Ehsan M. Kermani](https://www.linkedin.com/in/ehsanmkermani), and [Slobodan Markovic](https://www.linkedin.com/in/slobodan-markovic).\n",
"\n",
"This notebook was recently revamped by [Alex Aklson](https://www.linkedin.com/in/aklson/). I hope you found this lab session interesting. Feel free to contact me if you have any questions!"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"This notebook is part of a course on **Coursera** called *Data Visualization with Python*. If you accessed this notebook outside the course, you can take this course online by clicking [here](http://cocl.us/DV0101EN_Coursera_Week2_LAB2)."
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"editable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"<hr>\n",
"\n",
"Copyright &copy; 2019 [Cognitive Class](https://cognitiveclass.ai/?utm_source=bducopyrightlink&utm_medium=dswb&utm_campaign=bdu). This notebook and its source code are released under the terms of the [MIT License](https://bigdatauniversity.com/mit-license/)."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python",
"language": "python",
"name": "conda-env-python-py"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.10"
},
"widgets": {
"state": {},
"version": "1.1.2"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment