<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Sea Ice Extent
This notebook downloads and renders a current graph of the global sea ice extent that begins in 1979 until now (may with 1 day delay or based on availability of the raw data from the NSIDC). It is a real time data.
The Arctic and Antarctic SIC data can be downloaded respectively from<br> 
ftp
Step1:  2. Set up some constants
Step2:  3. Update SIC data
3.1 Customized file operation functions
Prepare and load the data files. Downloading and updating as necessary
Step3:  3.2 Load SIC data
Step4:  3.3 Simplify SIC data to only keep necessary variables
Step5:  4. Arctic SIC
Step6:  5. Antarctic SIC
Step7:  6. Global SIC
<ASSISTANT_TASK:>
Python Code:
%matplotlib inline
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import datetime
import os
import calendar
import urllib2
import urlparse
from matplotlib.pylab import rcParams
rcParams['figure.figsize'] = 12, 6
Explanation: Sea Ice Extent
This notebook downloads and renders a current graph of the global sea ice extent that begins in 1979 until now (may with 1 day delay or based on availability of the raw data from the NSIDC). It is a real time data.
The Arctic and Antarctic SIC data can be downloaded respectively from<br> 
ftp://sidads.colorado.edu/DATASETS/NOAA/G02135/south/daily/data/S_seaice_extent_daily_v3.0.csv<br>
ftp://sidads.colorado.edu/DATASETS/NOAA/G02135/north/daily/data/N_seaice_extent_daily_v3.0.csv. However, sometimes you may have to download them manually as their names may change with versions. The two datasets would be combined togeter to get global SIC during the procedure of analysis.
This notebook is inspired by the tutorials from Emma M, and all credit goes to Emma M. Besides this notebook only puts original notebooks for Arctic, Antarctic an Global SICs into a single one, the source code is adjusted a little bit to run smoothly under python 2.7. In addition, the data links are updated to the latest version of v3.0.
1. Load all needed libraries
End of explanation
LOCAL_DATA_PATH = '.\data'
LOCAL_OUTPUT_PATH = '.\image'
DATA_URLS = {
    's': 'ftp://sidads.colorado.edu/DATASETS/NOAA/G02135/south/daily/data/S_seaice_extent_daily_v3.0.csv',
    'n': 'ftp://sidads.colorado.edu/DATASETS/NOAA/G02135/north/daily/data/N_seaice_extent_daily_v3.0.csv'
}
pd.set_option('display.max_rows', 5)
Explanation: 2. Set up some constants
End of explanation
# Check if necessary directories exist
def mkdir_if_necessary(dir):
    try:
        os.stat(dir)
    except:
        os.mkdir(dir)       
# Check if our data files exist already
def data_files_exist():
    for key, url in DATA_URLS.items():
        filename = os.path.split(urlparse.urlsplit(url).path)[-1]
        if os.path.isfile(os.path.join(LOCAL_DATA_PATH, filename)):
            return True
        else:
            return False
# Load the data from disk and return the dataframes
def load_data_files():
    sea_ice_indexes = {}
    for key, url in DATA_URLS.items():
        filename = os.path.split(urlparse.urlsplit(url).path)[-1]
        sea_ice_indexes[key] = pd.read_csv(os.path.join(LOCAL_DATA_PATH, filename), skiprows=[1])
    for key in sea_ice_indexes.keys():
        sea_ice_indexes[key].rename(columns=lambda x: x.strip(), inplace=True)
        sea_ice_indexes[key]['Date'] = sea_ice_indexes[key].apply(lambda row: datetime.date(
                                       row['Year'], row['Month'], row['Day']), axis=1)
        sea_ice_indexes[key]['Day of Year'] = sea_ice_indexes[key].apply(lambda row: row['Date'].timetuple().tm_yday, axis=1)
        sea_ice_indexes[key]['Date'] = pd.to_datetime(sea_ice_indexes[key]['Date'])
    sea_ice_indexes['n'] = sea_ice_indexes['n'][['Extent', 'Date']]
    sea_ice_indexes['s'].rename(columns={'Extent': 'S Extent'}, inplace=True)
    sea_ice_indexes['n'].rename(columns={'Extent': 'N Extent'}, inplace=True)
    return sea_ice_indexes
        
# Check if our data appears to be out of date
def data_is_fresh(sea_ice_indexes):
    for key, sea_ice_index in sea_ice_indexes.items():
        today = datetime.date.today()
        print('Data is {0} day(s) old'.format((datetime.datetime.now() - sea_ice_index['Date'].iloc[-1]).days))
        if (datetime.datetime.now() - sea_ice_index['Date'].iloc[-1]).days >= 2:
            return False
        else:
            return True
# Update to latest data files
def refresh_data_files():
    for key, url in DATA_URLS.items():
        filename = os.path.join(LOCAL_DATA_PATH, os.path.split(urlparse.urlsplit(url).path)[-1])
        #with urllib.urlopen(url) as response, open(filename, 'wb') as out_file:
        #    shutil.copyfileobj(response, out_file)
        response = urllib2.urlopen(url)
        html = response.read()
        with open(filename, 'wb') as out_file:
            out_file.write(html)
    
# Prepare and load the data files downloading and updating as necessary
def prep_data_files():
    mkdir_if_necessary(LOCAL_DATA_PATH)
    mkdir_if_necessary(LOCAL_OUTPUT_PATH)
    if data_files_exist():
        print('Data files exist')
        sea_ice_indexes = load_data_files()
        if data_is_fresh(sea_ice_indexes):
            print('Data files are up to date')
        else:
            print('Data files are outdated')
            refresh_data_files()
            sea_ice_indexes = load_data_files()
            print('Data files have been updated')
    else:
        print('No data files found')
        refresh_data_files()
        sea_ice_indexes = load_data_files()
        print('Data files have been downloaded')
    return sea_ice_indexes
Explanation: 3. Update SIC data
3.1 Customized file operation functions
Prepare and load the data files. Downloading and updating as necessary
End of explanation
sea_ice_indexes = prep_data_files()
global_sea_ice_index = pd.merge(left=sea_ice_indexes['s'],
                                right=sea_ice_indexes['n'],
                                on='Date')
global_sea_ice_index['Total Extent'] = global_sea_ice_index['S Extent'] + global_sea_ice_index['N Extent']
global_sea_ice_index.index = global_sea_ice_index['Day of Year']
global_sea_ice_index
Explanation: 3.2 Load SIC data
End of explanation
global_sea_ice_index.drop(['Missing','Source Data','Day','Date','Month', 'Day of Year'], axis=1, inplace=True)
global_sea_ice_index.index = global_sea_ice_index.index.astype(datetime.datetime)
global_sea_ice_index
Explanation: 3.3 Simplify SIC data to only keep necessary variables
End of explanation
for key, grp in global_sea_ice_index.groupby(['Year']):
    if (key >= 1979 and key <= 2018) or key >= 2016:
        if key == 2017:
            plt.plot(grp['N Extent'], label=key, color="#ff00bb")
        elif key == 2016:
            plt.plot(grp['N Extent'], label=key, color="#cc00ff")
        else:
            plt.plot(grp['N Extent'], label=key)
plt.title('NSIDC Arctic Sea Ice Extent (Updated {0})'.format(datetime.date.today().isoformat()))
plt.xlabel("Month")
plt.xlim(1,366)
plt.xticks(np.linspace(1,366,13), calendar.month_abbr[1:13], rotation=0)
plt.legend(loc='best')
plt.legend(bbox_to_anchor=(1.01, 1), ncol=2, fontsize=10)
plt.ylabel("Sea Ice Extent (10^6 sq. km)")
plt.savefig(r'image\arctic_sea_ice_{0}.png'.format(datetime.date.today().isoformat()),
        dpi=300, facecolor='w', edgecolor='w',
        orientation='portrait', papertype=None, format='png',
        transparent=False, bbox_inches='tight', pad_inches=0.1,
        frameon=None)
Explanation: 4. Arctic SIC
End of explanation
for key, grp in global_sea_ice_index.groupby(['Year']):
    if (key >= 1979 and key <= 2018) or key >= 2016:
        if key == 2017:
            plt.plot(grp['S Extent'], label=key, color="#ff00bb")
        elif key == 2016:
            plt.plot(grp['S Extent'], label=key, color="#cc00ff")
        else:
            plt.plot(grp['S Extent'], label=key)
plt.title('NSIDC Antarctic Sea Ice Extent (Updated {0})'.format(datetime.date.today().isoformat()))
plt.xlabel("Month")
plt.xlim(1,366)
plt.xticks(np.linspace(1,366,13), calendar.month_abbr[1:13], rotation=0)
plt.legend(loc='best')
plt.legend(bbox_to_anchor=(1.01, 1), ncol=2, fontsize=10)
plt.ylabel("Sea Ice Extent (10^6 sq. km)")
plt.savefig(r'image\antarctic_sea_ice_{0}.png'.format(datetime.date.today().isoformat()),
        dpi=300, facecolor='w', edgecolor='w',
        orientation='portrait', papertype=None, format='png',
        transparent=False, bbox_inches='tight', pad_inches=0.1,
        frameon=None)
Explanation: 5. Antarctic SIC
End of explanation
for key, grp in global_sea_ice_index.groupby(['Year']):
    if (key >= 1979 and key <= 2018) or key >= 2016:
        if key == 2017:
            plt.plot(grp['Total Extent'], label=key, color="#ff00bb")
        elif key == 2016:
            plt.plot(grp['Total Extent'], label=key, color="#cc00ff")
        else:
            plt.plot(grp['Total Extent'], label=key)
plt.title('NSIDC Global Sea Ice Extent (Updated {0})'.format(datetime.date.today().isoformat()))
plt.xlabel("Month")
plt.xlim(1,366)
plt.xticks(np.linspace(1,366,13), calendar.month_abbr[1:13], rotation=0)
plt.legend(loc='best')
plt.legend(bbox_to_anchor=(1.01, 1), ncol=2, fontsize=10)
plt.ylabel("Sea Ice Extent (10^6 sq. km)")
output_filename = 'global_sea_ice_{0}.png'.format(datetime.date.today().isoformat())
output_path = os.path.join(LOCAL_OUTPUT_PATH, output_filename)
plt.savefig(output_path,
        dpi=300, facecolor='w', edgecolor='w',
        orientation='portrait', papertype=None, format='png',
        transparent=False, bbox_inches='tight', pad_inches=0.1,
        frameon=None)
Explanation: 6. Global SIC
End of explanation
<END_TASK>