Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
@@ -157,6 +157,99 @@ def calculate_total_new_snow(df):
|
|
157 |
snow_df['day_group'] = snow_df['datetime'].apply(
|
158 |
lambda x: x.date() if x.hour >= 9 else (x - pd.Timedelta(days=1)).date()
|
159 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
160 |
|
161 |
def process_daily_snow(group):
|
162 |
"""Sum up ONLY the 3-hour snowfall amounts for each day period"""
|
|
|
157 |
snow_df['day_group'] = snow_df['datetime'].apply(
|
158 |
lambda x: x.date() if x.hour >= 9 else (x - pd.Timedelta(days=1)).date()
|
159 |
)
|
160 |
+
def process_daily_snow(group):
|
161 |
+
"""Sum up ONLY the 3-hour snowfall amounts for each day period"""
|
162 |
+
# Sort by time to ensure proper sequence
|
163 |
+
group = group.sort_values('datetime')
|
164 |
+
|
165 |
+
# Sum only the valid 3-hour amounts, treating NaN as 0
|
166 |
+
valid_amounts = group['snowfall_3hr'].fillna(0)
|
167 |
+
daily_total = valid_amounts.sum()
|
168 |
+
|
169 |
+
return daily_total
|
170 |
+
|
171 |
+
def create_plots(df):
|
172 |
+
"""Create all weather plots including SWE estimates"""
|
173 |
+
# Create figure with adjusted height and spacing
|
174 |
+
fig = plt.figure(figsize=(20, 24))
|
175 |
+
|
176 |
+
# Calculate height ratios for different plots
|
177 |
+
height_ratios = [1, 1, 1, 1, 1] # Equal height for all plots
|
178 |
+
gs = GridSpec(5, 1, figure=fig, height_ratios=height_ratios)
|
179 |
+
gs.update(hspace=0.4) # Increase vertical spacing between plots
|
180 |
+
|
181 |
+
# Temperature plot
|
182 |
+
ax1 = fig.add_subplot(gs[0])
|
183 |
+
ax1.plot(df['datetime'], df['temp'], label='Temperature', color='red')
|
184 |
+
ax1.plot(df['datetime'], df['wind_chill'], label='Wind Chill', color='blue')
|
185 |
+
ax1.set_title('Temperature and Wind Chill Over Time', pad=20)
|
186 |
+
ax1.set_xlabel('Date')
|
187 |
+
ax1.set_ylabel('Temperature (°F)')
|
188 |
+
ax1.legend()
|
189 |
+
ax1.grid(True)
|
190 |
+
ax1.tick_params(axis='x', rotation=45)
|
191 |
+
|
192 |
+
# Wind speed plot
|
193 |
+
ax2 = fig.add_subplot(gs[1])
|
194 |
+
ax2.plot(df['datetime'], df['wind_speed'], label='Wind Speed', color='blue')
|
195 |
+
ax2.plot(df['datetime'], df['wind_gust'], label='Wind Gust', color='orange')
|
196 |
+
ax2.set_title('Wind Speed and Gusts Over Time', pad=20)
|
197 |
+
ax2.set_xlabel('Date')
|
198 |
+
ax2.set_ylabel('Wind Speed (mph)')
|
199 |
+
ax2.legend()
|
200 |
+
ax2.grid(True)
|
201 |
+
ax2.tick_params(axis='x', rotation=45)
|
202 |
+
|
203 |
+
# Snow depth plot
|
204 |
+
ax3 = fig.add_subplot(gs[2])
|
205 |
+
ax3.plot(df['datetime'], df['snow_depth'], color='blue', label='Snow Depth')
|
206 |
+
ax3.set_title('Snow Depth Over Time', pad=20)
|
207 |
+
ax3.set_xlabel('Date')
|
208 |
+
ax3.set_ylabel('Snow Depth (inches)')
|
209 |
+
ax3.grid(True)
|
210 |
+
ax3.tick_params(axis='x', rotation=45)
|
211 |
+
|
212 |
+
# Daily new snow bar plot
|
213 |
+
ax4 = fig.add_subplot(gs[3])
|
214 |
+
snow_df = df[['datetime', 'snowfall_3hr']].copy()
|
215 |
+
snow_df['day_group'] = snow_df['datetime'].apply(
|
216 |
+
lambda x: x.date() if x.hour >= 9 else (x - pd.Timedelta(days=1)).date()
|
217 |
+
)
|
218 |
+
daily_snow = snow_df.groupby('day_group').apply(process_daily_snow).reset_index()
|
219 |
+
daily_snow.columns = ['date', 'new_snow']
|
220 |
+
|
221 |
+
# Create the bar plot
|
222 |
+
ax4.bar(daily_snow['date'], daily_snow['new_snow'], color='blue')
|
223 |
+
ax4.set_title('Daily New Snow (Sum of 3-hour amounts, 9 AM Reset)', pad=20)
|
224 |
+
ax4.set_xlabel('Date')
|
225 |
+
ax4.set_ylabel('New Snow (inches)')
|
226 |
+
ax4.tick_params(axis='x', rotation=45)
|
227 |
+
ax4.grid(True, axis='y', linestyle='--', alpha=0.7)
|
228 |
+
|
229 |
+
# Add value labels on top of each bar
|
230 |
+
for i, v in enumerate(daily_snow['new_snow']):
|
231 |
+
if v > 0: # Only label bars with snow
|
232 |
+
ax4.text(i, v, f'{v:.1f}"', ha='center', va='bottom')
|
233 |
+
|
234 |
+
# SWE bar plot
|
235 |
+
ax5 = fig.add_subplot(gs[4])
|
236 |
+
daily_swe = df.groupby('date')['swe'].mean()
|
237 |
+
ax5.bar(daily_swe.index, daily_swe.values, color='lightblue')
|
238 |
+
ax5.set_title('Snow/Water Equivalent', pad=20)
|
239 |
+
ax5.set_xlabel('Date')
|
240 |
+
ax5.set_ylabel('SWE (inches)')
|
241 |
+
ax5.tick_params(axis='x', rotation=45)
|
242 |
+
|
243 |
+
# Adjust layout
|
244 |
+
plt.subplots_adjust(top=0.95, bottom=0.05, left=0.1, right=0.95)
|
245 |
+
|
246 |
+
# Create separate wind rose figure
|
247 |
+
fig_rose = plt.figure(figsize=(10, 10))
|
248 |
+
ax_rose = WindroseAxes.from_ax(fig=fig_rose)
|
249 |
+
create_wind_rose(df, ax_rose)
|
250 |
+
fig_rose.subplots_adjust(top=0.95, bottom=0.05, left=0.1, right=0.95)
|
251 |
+
|
252 |
+
return fig, fig_rose
|
253 |
|
254 |
def process_daily_snow(group):
|
255 |
"""Sum up ONLY the 3-hour snowfall amounts for each day period"""
|