Assignment 2

Before working on this assignment please read these instructions fully. In the submission area, you will notice that you can click the link to Preview the Grading for each step of the assignment. This is the criteria that will be used for peer grading. Please familiarize yourself with the criteria before beginning the assignment.

An NOAA dataset has been stored in the file data/C2A2_data/BinnedCsvs_d400/fb441e62df2d58994928907a91895ec62c2c42e6cd075c2700843b89.csv. The data for this assignment comes from a subset of The National Centers for Environmental Information (NCEI) Daily Global Historical Climatology Network (GHCN-Daily). The GHCN-Daily is comprised of daily climate records from thousands of land surface stations across the globe.

Each row in the assignment datafile corresponds to a single observation.

The following variables are provided to you:

  • id : station identification code
  • date : date in YYYY-MM-DD format (e.g. 2012-01-24 = January 24, 2012)
  • element : indicator of element type
    • TMAX : Maximum temperature (tenths of degrees C)
    • TMIN : Minimum temperature (tenths of degrees C)
  • value : data value for element (tenths of degrees C)

For this assignment, you must:

  1. Read the documentation and familiarize yourself with the dataset, then write some python code which returns a line graph of the record high and record low temperatures by day of the year over the period 2005-2014. The area between the record high and record low temperatures for each day should be shaded.
  2. Overlay a scatter of the 2015 data for any points (highs and lows) for which the ten year record (2005-2014) record high or record low was broken in 2015.
  3. Watch out for leap days (i.e. February 29th), it is reasonable to remove these points from the dataset for the purpose of this visualization.
  4. Make the visual nice! Leverage principles from the first module in this course when developing your solution. Consider issues such as legends, labels, and chart junk.

The data you have been given is near Ann Arbor, Michigan, United States, and the stations the data comes from are shown on the map below.


In [1]:
%matplotlib notebook

In [2]:
import matplotlib.pyplot as plt
import mplleaflet
import pandas as pd

def leaflet_plot_stations(binsize, hashid):

    df = pd.read_csv('data/C2A2_data/BinSize_d{}.csv'.format(binsize))

    station_locations_by_hash = df[df['hash'] == hashid]

    lons = station_locations_by_hash['LONGITUDE'].tolist()
    lats = station_locations_by_hash['LATITUDE'].tolist()

    plt.figure(figsize=(8,8))

    plt.scatter(lons, lats, c='r', alpha=0.7, s=200)

    return mplleaflet.display()

leaflet_plot_stations(400,'fb441e62df2d58994928907a91895ec62c2c42e6cd075c2700843b89')


Out[2]:

In [161]:
import numpy as np
data= pd.read_csv('data/C2A2_data/BinSize_d400.csv')
city = "NEW YORK"
location_hash = data[data['NAME'].str.contains(city)].loc[:,'hash'].values[0]
file_path = 'data/C2A2_data/BinnedCsvs_d400/'+location_hash+'.csv'

city_df = pd.read_csv(file_path)
city_df.head()

#placeholder
#city_df = pd.read_csv('data/C2A2_data/BinnedCsvs_d400/fb441e62df2d58994928907a91895ec62c2c42e6cd075c2700843b89.csv')


Out[161]:
ID Date Element Data_Value
0 USC00216276 2012-05-01 TMIN 78
1 USC00218579 2007-12-22 TMIN -100
2 USC00216276 2012-05-01 TMAX 178
3 USC00218579 2013-11-24 TMIN -194
4 USC00214793 2011-02-18 TMAX 44

In [162]:
city_df['Date'] = pd.to_datetime(city_df['Date'].astype(str), format='%Y-%m-%d')
dates_2005_2014 = city_df[(city_df['Date']>= '2005-01-01') & (city_df['Date'] <= '2014-12-31')]
t_max = dates_2005_2014[dates_2005_2014['Element'] == 'TMAX']
t_min = dates_2005_2014[dates_2005_2014['Element'] == 'TMIN']

t_max['Month'] = dates_2005_2014['Date'].apply(lambda x : x.month)
t_max['Day'] = dates_2005_2014['Date'].apply(lambda x : x.day)
t_max.drop(t_max[(t_max['Day'] == 29) & (t_max['Month'] == 2)].index, inplace=True)

t_min['Month'] = dates_2005_2014['Date'].apply(lambda x : x.month)
t_min['Day'] = dates_2005_2014['Date'].apply(lambda x : x.day)
t_min.drop(t_min[(t_min['Day'] == 29) & (t_min['Month'] == 2)].index, inplace=True)


/opt/conda/lib/python3.5/site-packages/ipykernel/__main__.py:6: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
/opt/conda/lib/python3.5/site-packages/ipykernel/__main__.py:7: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
/opt/conda/lib/python3.5/site-packages/ipykernel/__main__.py:8: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
/opt/conda/lib/python3.5/site-packages/ipykernel/__main__.py:10: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
/opt/conda/lib/python3.5/site-packages/ipykernel/__main__.py:11: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
/opt/conda/lib/python3.5/site-packages/ipykernel/__main__.py:12: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy

In [164]:
f = lambda x: x.sort('Data_Value', ascending=True)
grouped_data_min = t_min.groupby(['Month', 'Day']).apply(f)
grouped_data_min = grouped_data_min.groupby(['Month', 'Day']).first().reset_index()

df_min = pd.DataFrame()
df_min['Date'] = grouped_data_min['Date']
df_min['TMIN'] = (grouped_data_min['Data_Value']/10)
df_min.head()


/opt/conda/lib/python3.5/site-packages/ipykernel/__main__.py:1: FutureWarning: sort(columns=....) is deprecated, use sort_values(by=.....)
  if __name__ == '__main__':
Out[164]:
Date TMIN
0 2009-01-01 -36.1
1 2010-01-02 -37.8
2 2010-01-03 -35.6
3 2010-01-04 -33.9
4 2010-01-05 -33.9

In [165]:
f = lambda x: x.sort('Data_Value', ascending=False)
grouped_data_max = t_max.groupby(['Month', 'Day']).apply(f)
grouped_data_max = grouped_data_max.groupby(['Month', 'Day']).first().reset_index()

df_max = pd.DataFrame()
df_max['Date'] = grouped_data_max['Date']
df_max['TMAX'] = (grouped_data_max['Data_Value']/10)
df_max.head()


/opt/conda/lib/python3.5/site-packages/ipykernel/__main__.py:1: FutureWarning: sort(columns=....) is deprecated, use sort_values(by=.....)
  if __name__ == '__main__':
Out[165]:
Date TMAX
0 2005-01-01 3.3
1 2007-01-02 3.3
2 2007-01-03 3.3
3 2007-01-04 4.4
4 2012-01-05 11.7

In [166]:
dates_2015 = city_df[city_df['Date'] >= '2015-01-01']
t_max_2015 = dates_2015[dates_2015['Element'] == 'TMAX']
t_min_2015 = dates_2015[dates_2015['Element'] == 'TMIN']

t_max_2015['Month'] = dates_2015['Date'].apply(lambda x : x.month)
t_max_2015['Day'] = dates_2015['Date'].apply(lambda x : x.day)
t_max_2015.drop(t_max_2015[(t_max_2015['Day'] == 29) & (t_max_2015['Month'] == 2)].index, inplace=True)

t_min_2015['Month'] = dates_2015['Date'].apply(lambda x : x.month)
t_min_2015['Day'] = dates_2015['Date'].apply(lambda x : x.day)
t_min_2015.drop(t_min_2015[(t_min_2015['Day'] == 29) & (t_min_2015['Month'] == 2)].index, inplace=True)


/opt/conda/lib/python3.5/site-packages/ipykernel/__main__.py:5: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
/opt/conda/lib/python3.5/site-packages/ipykernel/__main__.py:6: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
/opt/conda/lib/python3.5/site-packages/ipykernel/__main__.py:7: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
/opt/conda/lib/python3.5/site-packages/ipykernel/__main__.py:9: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
/opt/conda/lib/python3.5/site-packages/ipykernel/__main__.py:10: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
/opt/conda/lib/python3.5/site-packages/ipykernel/__main__.py:11: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy

In [167]:
f = lambda x: x.sort('Data_Value', ascending=True)
grouped_data_min_2015 = t_min_2015.groupby(['Month', 'Day']).apply(f)
grouped_data_min_2015 = grouped_data_min_2015.groupby(['Month', 'Day']).first().reset_index()

df_min_2015 = pd.DataFrame()
df_min_2015['Date'] = grouped_data_min_2015['Date']
df_min_2015['TMIN'] = (grouped_data_min_2015['Data_Value']/10)
df_min_2015.head()


/opt/conda/lib/python3.5/site-packages/ipykernel/__main__.py:1: FutureWarning: sort(columns=....) is deprecated, use sort_values(by=.....)
  if __name__ == '__main__':
Out[167]:
Date TMIN
0 2015-01-01 -19.4
1 2015-01-02 -18.3
2 2015-01-03 -19.4
3 2015-01-04 -27.8
4 2015-01-05 -26.7

In [168]:
f = lambda x: x.sort('Data_Value', ascending=False)
grouped_data_max_2015 = t_max_2015.groupby(['Month', 'Day']).apply(f)
grouped_data_max_2015 = grouped_data_max_2015.groupby(['Month', 'Day']).first().reset_index()

df_max_2015 = pd.DataFrame()
df_max_2015['Date'] = grouped_data_max_2015['Date']
df_max_2015['TMAX'] = (grouped_data_max_2015['Data_Value']/10)
df_max_2015.head()


/opt/conda/lib/python3.5/site-packages/ipykernel/__main__.py:1: FutureWarning: sort(columns=....) is deprecated, use sort_values(by=.....)
  if __name__ == '__main__':
Out[168]:
Date TMAX
0 2015-01-01 -1.7
1 2015-01-02 -1.7
2 2015-01-03 -1.7
3 2015-01-04 -3.3
4 2015-01-05 -17.8

In [169]:
result_min = df_min['TMIN']
result_max = df_max['TMAX']
result_min_2015 = df_min_2015['TMIN']
result_max_2015 = df_max_2015['TMAX']

broken_record_max = pd.DataFrame()
broken_record_min = pd.DataFrame()

broken_record_max['TMAX'] = df_max_2015[df_max_2015['TMAX'] > df_max['TMAX']]['TMAX']
broken_record_min['TMIN'] = df_min_2015[df_min_2015['TMIN'] < df_min['TMIN']]['TMIN']

In [176]:
plt.figure(figsize=(10,6))

plt.plot(result_min, '-', result_max, '-', zorder=1)
plt.scatter(broken_record_max.index, broken_record_max['TMAX'], marker='o', c='red', s=20, zorder=2)
plt.scatter(broken_record_min.index, broken_record_min['TMIN'], marker='o', c='red', s=20, zorder=2)

plt.xticks(np.array([0,31,60,91,121,152,182,213,244,274,305,335]),
           ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
           fontsize=10, alpha=0.8)

plt.ylabel('Temperatures in C°', alpha=0.8)

#Not necessary
#plt.xlabel('Months', alpha=0.8)

plt.title('10 years Low & High temp. and 2015 breaking temp. for New York City', alpha=0.8)
plt.legend(['2005-2014 Low Temperatures', '2005-2014 High Temperatures', '2015 Low & High Breaking Temp.'])

for spine in plt.gca().spines.values():
    spine.set_visible(False)

plt.tick_params(top='off', bottom='off', left='off', right='off', labelleft='on', labelbottom='on')

ax = plt.gca()
ax.fill_between(range(len(res_min)), res_min, res_max, facecolor='blue', alpha=0.15)


Out[176]:
<matplotlib.collections.PolyCollection at 0x7fdf884441d0>

In [ ]: