<jupyter_start><jupyter_text>Extreme Temperatures in Stuttgart from 1999 to 2019Here is the Python code for plotting a line graph of the record high and record low temperatures by day of the year over the period 2009-2018 in the area of Stuttgart, Germany.The area between the record high and record low temperatures for each day is shaded. A scatter of the 2019 data for any points (highs and lows) for which the ten year record (2009-2018) record high or record low was broken in 2019.Leap days (i.e. February 29th) is removed for the purpose of this visualization.The climate data used in this file comes from a subset of The National Centers for Environmental Information (NCEI) [Daily Global Historical Climatology Network](https://www1.ncdc.noaa.gov/pub/data/ghcn/daily/readme.txt) (GHCN-Daily). The GHCN-Daily is comprised of daily climate records from thousands of land surface stations across the globe.You must install the python package `mplleaflet` to run the geo plotting below.<jupyter_code>import matplotlib
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

print('matplotlib version: ', matplotlib.__version__)
print('pandas version: ', pd.__version__)
print('numpy version: ', np.version.version)
# load the cvs files and concatenate them together to one dataframe

df1 = pd.read_csv('data/Stuttgart_climate_19990101-20081231.csv')
df2 = pd.read_csv('data/Stuttgart_climate_20090101-20191231.csv')

frames = [df1, df2]

data = pd.concat(frames)
data.head()
# how many records?
len(data)
# TMAX and TMIN are the columns we are going to use.
# drop lines where value of TAVG
data.dropna(subset = ['TMAX', 'TMIN'], inplace = True)
# how many records?
len(data)
df_t = data.drop(columns=['PRCP', 'PRCP_ATTRIBUTES', 'SNWD', 
                          'SNWD_ATTRIBUTES', 'TAVG_ATTRIBUTES', 
                          'TMAX_ATTRIBUTES', 'TMIN_ATTRIBUTES'])
df_t.head()
import mplleaflet

stations = data[['STATION', 'NAME', 'LATITUDE', 'LONGITUDE', 'ELEVATION']]

s = stations.drop_duplicates()

# plot the stations on a map

lons = s.LONGITUDE.tolist()
lats = s.LATITUDE.tolist()

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

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

mplleaflet.display()
pd.DatetimeIndex?
# get the handle of the date_idx object
date_idx = pd.DatetimeIndex(data.DATE)

date_idx
date_idx.max()
# remove the leap days: Feb 29
data = data[~((date_idx.is_leap_year) & (date_idx.month == 2) & (date_idx.day == 29))]

# how many records remaining?
len(data)
# recompute the date_idx
date_idx = pd.DatetimeIndex(data.DATE)
# create 'month' and 'day' indices for further grouping
data['Month'] = date_idx.month
data['Day'] = date_idx.day

# split the data
split_date = '2019-01-01'
data_2019 = data[date_idx >= split_date]
data = data[date_idx < split_date]
# get the maximum temperature records
temp_max = data.groupby(["Month", "Day"])['TMAX'].max()

temp_max.head()
# get the minimum temperature records
temp_min = data.groupby(["Month", "Day"])['TMIN'].min()

temp_min.head()
# get the 2019 maximum temperatures
temp_2019_max = data_2019.groupby(["Month", "Day"])['TMAX'].max()

temp_2019_max.head()
# get the 2019 minimum temperatures
temp_2019_min = data_2019.groupby(["Month", "Day"])['TMIN'].min()

temp_2019_min.head()
# days in 2019 whose max or min temperatures broke historical records in last 10 years
new_max_2019 = (temp_2019_max > temp_max)
print(np.sum(new_max_2019))

new_min_2019 = (temp_2019_min < temp_min)
print(np.sum(new_min_2019))
%matplotlib inline
import matplotlib.pyplot as plt
import matplotlib as mpl
mpl.rcParams['figure.figsize'] = (16, 8)
observation_axis = np.arange('2019-01-01', '2020-01-01', dtype='datetime64[D]')
observation_axis = np.array(list(map(pd.to_datetime, observation_axis)))
plt.plot?
import matplotlib.dates as mdates

plt.suptitle("1999-2018 daily extreme temperatures with highlighted new records in 2019 (°C)", fontsize = 18)
plt.title("Region of Stuttgart, Germany", fontsize=16)
plt.ylabel('Temperature in Degree Celsius')

# This is crucial, see https://stackoverflow.com/questions/47404653/pandas-0-21-0-timestamp-compatibility-issue-with-matplotlib
pd.plotting.register_matplotlib_converters()  

# historical daily extremes
plt.plot(observation_axis, temp_min.to_numpy(), '-o', color='#69cdf8', ms=2, alpha=0.75) 
plt.plot(observation_axis, temp_max.to_numpy(), '-o', color='#ffb665', ms=2, alpha=0.75)

# 2019 new records
plt.plot(observation_axis[new_max_2019], temp_2019_max[new_max_2019], 'r^',
         observation_axis[new_min_2019], temp_2019_min[new_min_2019], 'bv', 
         ms=8, alpha=1.0)


plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%b'))
plt.gca().xaxis.set_major_locator(mdates.MonthLocator())

plt.legend(['Lowest temperature of the day 1999-2018', 
            'Highest temperature of the day 1999-2018', 
            '2019 new highs', '2019 new lows'], 
            frameon = False)
           # loc='center left', bbox_to_anchor=(1.0, 0.5), prop={'size':12})

plt.gca().fill_between(observation_axis, temp_min, temp_max, facecolor='grey', alpha=0.18)

# remove unnecessary frames
plt.gca().spines['top'].set_visible(False)
plt.gca().spines['right'].set_visible(False)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.12590891695369308, 'fraction_numerical': 0.05434366628396479, 'mean_word_length': 5.163915094339623, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 2, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '251339', 'license': 'MIT', 'n_tokens_mistral': 2011, 'n_tokens_neox': 1766, 'n_words': 488, 'path': 'extreme-temperatures-stuttgart .ipynb', 'repo_name': 'nnworkspace/climate-watch', 'size': '5226'}