# -*- coding: utf-8 -*- """ @author: John Rachlin @date : February 24, 2022 @file : cherry.py Analysis of the full-flowering day-of-year for cherry blossums in Kyoto Japan. Why is this significant? Scientists are interested in understanding periodic biological phenomena (flowering, breeding, migration) especially as it relates to climatic conditions. (The scientific study of these types of phenomena is known as PHENOLOGY.) Data source: https://www.ncei.noaa.gov/pub/data/paleo/historical/phenology/japan/LatestVersion/KyotoFullFlower7.xls Data for 2020 and 2021 added to data set. 2020: March 30 - based on Japan Meterological Corporation (JMC) 2020 forecast. 2021: March 26 - based on reported actual (Osaka University) """ import csv import matplotlib.pyplot as plt def avg(L): if len(L) > 0: return sum(L) / len(L) else: return None def read_flowering_data(filename): """ Read cherry blossum full-flowering day-of-year data. Return a dictionary mapping year to day-of-year (of full blossums) """ years = [] flowering_doy = [] with open(filename) as file: reader = csv.reader(file, delimiter=',') next(reader) for row in reader: year = int(row[0]) if row[1] != '': # value provided doy = int(row[1]) else: # no value provided doy = flowering_doy[-1] # assume doy is same as last year years.append(year) flowering_doy.append(doy) return years, flowering_doy # returning a tuple of values! def moving_average(L, window_size=10): """ Compute a moving average using a specified window size. """ mavg = [] for i in range(len(L)): lower = max(i - window_size // 2, 0) upper = i + window_size // 2 window = L[lower:upper] smooth = avg(window) mavg.append(smooth) return mavg def plot_blossum_day_history(years, doy): """ Plot the day-of-year full blossuming by year for all available years """ mavg30 = moving_average(doy, window_size = 30) mavg10 = moving_average(doy, window_size = 10) mavg100 = moving_average(doy, window_size = 100) plt.figure(figsize=(10,6), dpi=200) plt.title("Cherry Blossom full blossom date (Kyoto, Japan)") plt.xlabel("Year") plt.ylabel("Date") plt.scatter(years, doy, marker='.', color='#FF66B2', label='Full blossom date') # The color of cherry blossums! plt.plot(years, mavg10, color='m', label='10 year moving avg') plt.plot(years, mavg30, color='b', label='30 year moving avg') plt.plot(years, mavg100, color='k', label='100 year moving avg') plt.yticks([80,90,100,110,120], ['Mar 21', 'Mar 31', 'Apr 10', 'Apr 20', 'Apr 30']) # Highlight 2021 (Record) plt.text(1900, 84.5, '2021 --->') # Outliers are interesting! # There was a global temperature reduction at that time. # See global_temps.png plt.text(1333,124, '1323 (May 4th)') plt.text(1416, 86, '1409') # Until 2021, this was the previous record year # Annotate figure with "The little ice-age" - a period of cooling # occurring between 1400-1800, though, according to wikipedia, # some experts prefer the alternative timespan of 1300-1850 plt.text(1300,84, '<- - - - - -------- The "Little Ice Age" ---------- - ->') # Include a legend plt.legend(facecolor='lightgrey', edgecolor='black', loc='upper left') plt.grid() plt.show() def main(): # Read the data into a dictionary (year -> doy) years, doys = read_flowering_data('cherry.csv') # Visualize full-blossum day-of-year (Kyoto, Japan) plot_blossum_day_history(years, doys) if __name__ == '__main__': main()