Created
September 28, 2025 17:37
-
-
Save matthewwiese/84b53d28c942ebd067b177ddc5571acb to your computer and use it in GitHub Desktop.
Total Annual Precipitation at Cornell University Using NRCC CLIMOD 2 Data
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Station | 1980 | 1981 | 1982 | 1983 | 1984 | 1985 | 1986 | 1987 | 1988 | 1989 | 1990 | 1991 | 1992 | 1993 | 1994 | 1995 | 1996 | 1997 | 1998 | 1999 | 2000 | 2001 | 2002 | 2003 | 2004 | 2005 | 2006 | 2007 | 2008 | 2009 | 2010 | 2011 | 2012 | 2013 | 2014 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| BROOKTONDALE 1.3 NW | M | M | ||||||||||||||||||||||||||||||||||||||||||||
| BROOKTONDALE 2.7 SE | M | M | M | |||||||||||||||||||||||||||||||||||||||||||
| CAROLINE CENTER 0.1 SE | M | M | M | M | M | M | M | M | M | M | M | M | M | M | ||||||||||||||||||||||||||||||||
| DANBY 2.5 NE | M | |||||||||||||||||||||||||||||||||||||||||||||
| EAST ITHACA 2.6 ENE | M | M | M | |||||||||||||||||||||||||||||||||||||||||||
| EAST ITHACA 3.6 SE | M | |||||||||||||||||||||||||||||||||||||||||||||
| EAST ITHACA 4.7 E | M | M | M | M | M | M | M | M | M | M | M | M | M | M | M | 46.58 | M | |||||||||||||||||||||||||||||
| ENFIELD 0.8 ENE | M | M | M | M | M | M | M | |||||||||||||||||||||||||||||||||||||||
| FREEVILLE 1 NE | 31.69 | 39.5 | 29.51 | 37.27 | 41.41 | 32.48 | 38.01 | M | M | 36.95 | M | M | 37.96 | M | 43.44 | 34.66 | 47.57 | M | M | 31.42 | 37.96 | 31.79 | 38.32 | 43.06 | M | 39.67 | M | M | 40.71 | 35.41 | 39.02 | 47.56 | 33.32 | 41.98 | 36.85 | 37.71 | 32.99 | M | 44.01 | 41.71 | 34.26 | 47.25 | M | 35.48 | 36.74 | |
| FREEVILLE 1.5 NE | M | M | M | M | M | M | M | M | M | M | M | M | M | M | M | M | M | M | M | |||||||||||||||||||||||||||
| FREEVILLE 2.6 N | M | M | M | M | M | M | ||||||||||||||||||||||||||||||||||||||||
| FREEVILLE 3.7 W | M | M | M | 49.75 | 37.01 | 43.53 | 41.79 | 38.96 | 37.27 | M | M | 43.95 | M | M | 35.96 | 43.49 | 41.38 | |||||||||||||||||||||||||||||
| FREEVILLE 4.2 S | M | |||||||||||||||||||||||||||||||||||||||||||||
| GROTON 0.5 NW | M | 44.91 | M | 41.60 | 50.77 | 41.06 | 44.37 | 42.46 | 42.67 | 38.49 | 49.98 | 50.10 | 45.81 | 36.82 | 53.55 | 41.30 | M | 45.49 | ||||||||||||||||||||||||||||
| GROTON 0.6 ESE | M | M | M | M | M | M | M | |||||||||||||||||||||||||||||||||||||||
| GROTON 3.2 SSW | M | M | M | M | 38.78 | 42.69 | M | M | M | M | 36.45 | 49.97 | M | M | M | |||||||||||||||||||||||||||||||
| ITHACA 0.2 N | M | |||||||||||||||||||||||||||||||||||||||||||||
| ITHACA 0.5 N | M | M | ||||||||||||||||||||||||||||||||||||||||||||
| ITHACA 1.1 SE | M | M | M | M | M | M | M | M | M | |||||||||||||||||||||||||||||||||||||
| ITHACA 1.2 WNW | M | |||||||||||||||||||||||||||||||||||||||||||||
| ITHACA 1.8 WSW | M | M | M | M | ||||||||||||||||||||||||||||||||||||||||||
| ITHACA 2.0 ESE | M | M | M | M | M | |||||||||||||||||||||||||||||||||||||||||
| ITHACA 2.2 NW | M | M | M | M | M | M | M | M | M | M | ||||||||||||||||||||||||||||||||||||
| ITHACA 2.5 SW | M | |||||||||||||||||||||||||||||||||||||||||||||
| ITHACA 2.6 NW | M | M | M | M | M | M | M | M | M | M | M | M | M | M | M | M | M | |||||||||||||||||||||||||||||
| ITHACA 3.0 N | M | M | ||||||||||||||||||||||||||||||||||||||||||||
| ITHACA 3.0 NNW | M | M | ||||||||||||||||||||||||||||||||||||||||||||
| ITHACA 3.1 SSE | M | |||||||||||||||||||||||||||||||||||||||||||||
| ITHACA 3.4 SE | M | 36.59 | ||||||||||||||||||||||||||||||||||||||||||||
| ITHACA 4.3 S | M | M | ||||||||||||||||||||||||||||||||||||||||||||
| ITHACA 5.4 SSW | M | M | M | M | M | |||||||||||||||||||||||||||||||||||||||||
| ITHACA 6.3 E | M | |||||||||||||||||||||||||||||||||||||||||||||
| ITHACA 6.4 E | M | M | M | M | M | M | M | |||||||||||||||||||||||||||||||||||||||
| ITHACA 6.9 WNW | M | |||||||||||||||||||||||||||||||||||||||||||||
| ITHACA 8.5 W | M | M | ||||||||||||||||||||||||||||||||||||||||||||
| ITHACA CORNELL UNIV | 31.35 | 39.05 | M | 35.64 | 39.84 | 31.53 | 37.53 | 32.80 | M | 37.07 | 43.74 | 30.86 | 38.12 | M | 42.01 | 29.09 | 47.76 | 30.16 | 34.13 | 29.77 | 38.12 | 34.65 | 39.32 | 44.4 | 45.26 | 40.18 | 41.00 | 38.19 | 37.86 | 33.40 | 38.59 | 51.22 | 32.83 | 39.01 | 38.49 | 33.79 | 31.81 | 42.54 | 41.66 | 41.48 | 36.81 | 47.90 | 35.37 | 42.47 | 36.45 | |
| ITHACA TOMPKINS CNTY | M | |||||||||||||||||||||||||||||||||||||||||||||
| LANSING 4.3 NW | M | |||||||||||||||||||||||||||||||||||||||||||||
| LANSING 6.6 NW | M | M | M | M | M | M | M | M | M | M | M | |||||||||||||||||||||||||||||||||||
| LANSING 8.9 N | M | M | M | M | M | M | M | |||||||||||||||||||||||||||||||||||||||
| LANSING 9.1 NW | M | 40.06 | ||||||||||||||||||||||||||||||||||||||||||||
| NEWFIELD 2.5 S | M | M | M | M | M | M | M | M | M | M | M | M | M | |||||||||||||||||||||||||||||||||
| NEWFIELD HAMLET 0.9 E | M | |||||||||||||||||||||||||||||||||||||||||||||
| NEWFIELD HAMLET 1.7 NW | M | |||||||||||||||||||||||||||||||||||||||||||||
| NEWFIELD HAMLET 4.3 S | M | M | M | M | M | |||||||||||||||||||||||||||||||||||||||||
| SLATERVILLE SPRINGS 0.5 ESE | M | M | ||||||||||||||||||||||||||||||||||||||||||||
| SLATERVILLE SPRINGS 1.0 S | M | M | M | M | ||||||||||||||||||||||||||||||||||||||||||
| SOUTH HILL 0.4 ESE | M | M | M | M | M | M | M | |||||||||||||||||||||||||||||||||||||||
| SPENCER 9.5 N | M | |||||||||||||||||||||||||||||||||||||||||||||
| TRUMANSBURG 0.3 NNE | M | M | M | |||||||||||||||||||||||||||||||||||||||||||
| TRUMANSBURG 0.3 SSE | M | |||||||||||||||||||||||||||||||||||||||||||||
| TRUMANSBURG 0.4 WNW | M | M | M | M | M | M | M | M | M | M | M | M | M | M | M | M | ||||||||||||||||||||||||||||||
| TRUMANSBURG 2.4 SSE | M | |||||||||||||||||||||||||||||||||||||||||||||
| TRUMANSBURG 4.3 NE | M |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import pandas as pd | |
| import matplotlib.pyplot as plt | |
| import numpy as np | |
| # Read the data | |
| df = pd.read_csv('combined_precipitation.csv') | |
| # Filter for Ithaca Cornell University | |
| ithaca_row = df[df['Station'] == 'ITHACA CORNELL UNIV'].iloc[0] | |
| # Extract years and precipitation values | |
| years = list(range(1980, 2025)) | |
| precip_values = [] | |
| for year in years: | |
| value = ithaca_row[str(year)] | |
| if value == 'M' or pd.isna(value): | |
| precip_values.append(np.nan) | |
| else: | |
| precip_values.append(float(value)) | |
| # Create DataFrame for easier handling | |
| data = pd.DataFrame({ | |
| 'Year': years, | |
| 'Precipitation': precip_values | |
| }) | |
| # Identify valid (non-missing) data points | |
| valid_mask = ~np.isnan(data['Precipitation']) | |
| valid_years = data['Year'][valid_mask].values | |
| valid_precip = data['Precipitation'][valid_mask].values | |
| # Create moving average trend line | |
| # Use 5-year moving average to show long-term trends | |
| window_size = 5 | |
| if len(valid_years) >= window_size: | |
| # Calculate moving average for valid data | |
| moving_avg = pd.Series(data['Precipitation']).rolling(window=window_size, center=True).mean() | |
| # Get non-null moving average values and corresponding years | |
| valid_ma_mask = ~moving_avg.isna() | |
| ma_years = data['Year'][valid_ma_mask].values | |
| ma_values = moving_avg[valid_ma_mask].values | |
| # Create the plot | |
| fig, ax = plt.subplots(figsize=(14, 8)) | |
| # Plot actual data points | |
| ax.scatter(valid_years, valid_precip, color='#2E86AB', s=50, alpha=0.8, | |
| label='Observed Annual Precipitation', zorder=3) | |
| # Plot moving average trend line | |
| if len(valid_years) >= window_size: | |
| ax.plot(ma_years, ma_values, color='#A23B72', linewidth=2.5, | |
| alpha=0.7, label=f'{window_size}-Year Moving Average', zorder=2) | |
| # Connect consecutive valid points with light lines | |
| ax.plot(valid_years, valid_precip, color='#2E86AB', linewidth=1, | |
| alpha=0.4, zorder=1) | |
| # Mark missing data years | |
| missing_years = data['Year'][~valid_mask].values | |
| if len(missing_years) > 0: | |
| ax.scatter(missing_years, [ax.get_ylim()[0] + 1] * len(missing_years), | |
| marker='x', color='red', s=60, alpha=0.6, | |
| label='Missing Data', zorder=3) | |
| # Calculate and add statistics | |
| mean_precip = np.nanmean(data['Precipitation']) | |
| ax.axhline(y=mean_precip, color='#F18F01', linestyle='--', alpha=0.7, | |
| linewidth=2, label=f'Long-term Average ({mean_precip:.1f} inches)') | |
| # Styling | |
| ax.set_xlabel('Year', fontsize=12, fontweight='bold') | |
| ax.set_ylabel('Annual Precipitation (inches)', fontsize=12, fontweight='bold') | |
| ax.set_title('Annual Precipitation Trends at Ithaca Cornell University\n1980-2024', | |
| fontsize=14, fontweight='bold', pad=20) | |
| ax.grid(True, alpha=0.3, linestyle='-', linewidth=0.5) | |
| ax.set_xlim(1979, 2025) | |
| # Add some styling | |
| ax.spines['top'].set_visible(False) | |
| ax.spines['right'].set_visible(False) | |
| ax.spines['left'].set_linewidth(0.5) | |
| ax.spines['bottom'].set_linewidth(0.5) | |
| # Legend | |
| ax.legend(loc='upper left', frameon=True, fancybox=True, shadow=True) | |
| # Add summary statistics as text box | |
| stats_text = f"""Data Summary: | |
| • Valid observations: {len(valid_years)}/{len(years)} years | |
| • Missing data: {len(missing_years)} years | |
| • Average precipitation: {mean_precip:.1f} inches | |
| • Min: {np.nanmin(data['Precipitation']):.1f} inches ({data.loc[data['Precipitation'].idxmin(), 'Year']}) | |
| • Max: {np.nanmax(data['Precipitation']):.1f} inches ({data.loc[data['Precipitation'].idxmax(), 'Year']})""" | |
| ax.text(0.02, 0.98, stats_text, transform=ax.transAxes, fontsize=9, | |
| verticalalignment='top', bbox=dict(boxstyle='round', facecolor='wheat', alpha=0.8)) | |
| plt.tight_layout() | |
| plt.savefig('ithaca_precipitation_1980_2024.png', dpi=300, bbox_inches='tight') | |
| plt.show() | |
| # Print missing years for reference | |
| print("Missing data years:", missing_years.tolist() if len(missing_years) > 0 else "None") | |
| print(f"Data coverage: {len(valid_years)}/{len(years)} years ({len(valid_years)/len(years)*100:.1f}%)") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment