AlexNiel5261 commited on
Commit
d455dd1
·
verified ·
1 Parent(s): 425b4ee

Upload 2 files

Browse files
Files changed (2) hide show
  1. requirements.txt +5 -5
  2. streamlit_app.py +195 -0
requirements.txt CHANGED
@@ -1,5 +1,5 @@
1
- polars
2
- pandas
3
- streamlit
4
- scikit-learn
5
- plotly
 
1
+ pandas
2
+ polars
3
+ streamlit
4
+ plotly
5
+ openmeteo-requests
streamlit_app.py ADDED
@@ -0,0 +1,195 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from collections import namedtuple
2
+ import altair as alt
3
+ import math
4
+ import pandas as pd
5
+ import streamlit as st
6
+ import polars as pl
7
+ import openmeteo_requests
8
+ from datetime import *
9
+
10
+ st.set_page_config(
11
+ page_title="Weather Data",
12
+ page_icon="🌤️",
13
+ layout='wide'
14
+ )
15
+
16
+ st.markdown("# Historic Weather Data for 3 BYU Campuses")
17
+ st.markdown("__Explore weather data gathered at all 3 BYU locations from any chosen date range. Observe visuals explaining the temperature, pressure, wind speed, and far more from all locations.__")
18
+
19
+ columns = st.columns(3, gap='medium')
20
+
21
+ openmeteo = openmeteo_requests.Client()
22
+
23
+ st.sidebar.markdown("_Note: Data is only present up to 4 days ago_")
24
+
25
+ length = st.sidebar.slider("Length of Time Period for Data (Days)", min_value=5, max_value=30, value=15)
26
+
27
+ campus = ['provo', 'hawaii', 'idaho']
28
+ locations = [(40.2518, 111.6493), (21.6419, 157.9267), (43.8145, 111.7833)]
29
+
30
+ start_day = st.sidebar.date_input("Start of Period for Data", value=(datetime.today() - timedelta(days=35)), min_value=date(2020, 1, 1), max_value=(datetime.today() - timedelta(days=(length+4))))
31
+
32
+ end = (start_day + timedelta(days=length)).strftime('%Y-%m-%d')
33
+ start = start_day.strftime('%Y-%m-%d')
34
+
35
+ zone_select = st.sidebar.selectbox("Choose Timezone", options=['Mountain Time', 'Hawaiian Time'])
36
+
37
+ zone = 'HST' if zone_select == 'Hawaiian Time' else 'MST'
38
+
39
+ variables = ['Temperature (F)', 'Apparent Temp (F)', 'Humidity (%)', 'Pressure (hPa)', 'Precipitation (in)', 'Rain (in)', 'Snowfall (in)', 'Cloud Cover (%)', 'Wind Speed (mph)', 'Snow Depth (m)']
40
+ variable_select = st.sidebar.selectbox("Choose variable of interest", options=variables)
41
+ variable_dict = {
42
+ 'Temperature (F)': 'temperature_2m',
43
+ 'Apparent Temp (F)': 'apparent_temperature',
44
+ 'Humidity (%)': 'relative_humidity_2m',
45
+ 'Pressure (hPa)': 'surface_pressure',
46
+ 'Precipitation (in)': 'precipitation',
47
+ 'Rain (in)': 'rain',
48
+ 'Snowfall (in)': 'snowfall',
49
+ 'Cloud Cover (%)': 'cloud_cover',
50
+ 'Wind Speed (mph)': 'wind_speed_10m',
51
+ 'Snow Depth (m)': 'snow_depth'
52
+ }
53
+
54
+ var = variable_dict[variable_select]
55
+
56
+ hi_lo = st.sidebar.selectbox("Daily Extremes", options=['Max', 'Min'])
57
+
58
+ daily_var = 'temperature_2m_max' if hi_lo == 'Max' else 'temperature_2m_min'
59
+
60
+ def request(url, lat, long, start, end, variable, time_unit, timezone):
61
+ params = {
62
+ "latitude": lat,
63
+ "longitude": long,
64
+ "start_date": start,
65
+ "end_date": end,
66
+ time_unit: variable,
67
+ "temperature_unit": "fahrenheit",
68
+ 'timezone': timezone,
69
+ 'precipitation_unit': 'inch',
70
+ 'wind_speed_unit': 'mph'
71
+ }
72
+ return openmeteo.weather_api(url, params=params)[0]
73
+
74
+ i = 0
75
+ temp_box = pl.DataFrame()
76
+ for location in locations:
77
+ actual = request("https://archive-api.open-meteo.com/v1/archive", location[0], location[1], start, end, var, 'hourly', zone)
78
+ forecasted = request("https://historical-forecast-api.open-meteo.com/v1/forecast", location[0], location[1], start, end, var, 'hourly', zone)
79
+
80
+ hourly_actual= actual.Hourly()
81
+ hourly_var_actual = hourly_actual.Variables(0).ValuesAsNumpy()
82
+
83
+ hourly_forecasted = forecasted.Hourly()
84
+ hourly_var_forecasted = hourly_forecasted.Variables(0).ValuesAsNumpy()
85
+
86
+ hourly_data = {"date-time": pd.date_range(
87
+ start = pd.to_datetime(hourly_actual.Time(), unit = "s", utc = True),
88
+ end = pd.to_datetime(hourly_actual.TimeEnd(), unit = "s", utc = True),
89
+ freq = pd.Timedelta(seconds = hourly_actual.Interval()),
90
+ inclusive = "left"
91
+ )}
92
+
93
+ hourly_data[var] = hourly_var_actual
94
+ hourly_data[f"forecast_{var}"] = hourly_var_forecasted
95
+
96
+ hourly_dataframe = pl.DataFrame(hourly_data)
97
+
98
+ hourly_dataframe = hourly_dataframe.with_columns(pl.col('date-time').dt.strftime('%Y-%m-%d').alias('date'))
99
+ hourly_dataframe = hourly_dataframe.with_columns(pl.col('date-time').dt.strftime("%H:%M:%S").alias('time'))
100
+
101
+ with columns[i]:
102
+ st.markdown(f"### {campus[i].title()}")
103
+ st.dataframe(hourly_dataframe.drop('date-time'))
104
+ st.dataframe(hourly_dataframe.select([var, f'forecast_{var}']).describe()[2:9])
105
+
106
+ current_campus = hourly_dataframe.with_columns(pl.lit(campus[i]).alias('campus'))
107
+
108
+ end_month = (datetime.today() - timedelta(days=4)).strftime('%Y-%m-%d')
109
+ start_month = (datetime.today() - timedelta(days=35)).strftime('%Y-%m-%d')
110
+ daily = request("https://archive-api.open-meteo.com/v1/archive", location[0], location[1], start_month, end_month, daily_var, 'daily', zone).Daily()
111
+
112
+ daily_data = {"date-time": pd.date_range(
113
+ start = pd.to_datetime(daily.Time(), unit = "s", utc = True),
114
+ end = pd.to_datetime(daily.TimeEnd(), unit = "s", utc = True),
115
+ freq = pd.Timedelta(seconds = daily.Interval()),
116
+ inclusive = "left"
117
+ )}
118
+ daily_data['temperature'] = daily.Variables(0).ValuesAsNumpy()
119
+
120
+ daily_df = pl.DataFrame(daily_data)
121
+ daily_df = daily_df.with_columns(pl.lit(campus[i]).alias('campus'))
122
+
123
+ if len(temp_box) == 0:
124
+ temp_box = pl.DataFrame(current_campus)
125
+ temp_line = daily_df
126
+ else:
127
+ temp_box = temp_box.vstack(current_campus)
128
+ temp_line = temp_line.vstack(daily_df)
129
+
130
+ i+=1
131
+
132
+ daily = alt.Chart(temp_line).mark_line().encode(
133
+ alt.X("date-time"),
134
+ alt.Y('temperature'),
135
+ color='campus'
136
+ ).properties(
137
+ title='Daily Temp Extremes Over Last Month',
138
+ width=300,
139
+ height=300
140
+ )
141
+
142
+
143
+ hourly_box = alt.Chart(temp_box).mark_boxplot().encode(
144
+ alt.X(var).scale(zero=False),
145
+ alt.Y("campus")
146
+ ).properties(
147
+ title='Hourly Readings',
148
+ width=400,
149
+ height=300
150
+ )
151
+
152
+
153
+ grouped = temp_box.select(['time', var, 'campus']).group_by(['time', 'campus']).mean()
154
+
155
+ hourly_average = alt.Chart(grouped).mark_line().encode(
156
+ x="time",
157
+ y=var,
158
+ color="campus"
159
+ ).properties(
160
+ title='Average Reading Given Time of Day',
161
+ width=400,
162
+ height=300
163
+ )
164
+
165
+
166
+ kpi_max = temp_box.select([var, 'campus']).group_by('campus').max()
167
+
168
+ pr_hi = kpi_max.filter(pl.col('campus') == 'provo')[var][0]
169
+ id_hi = kpi_max.filter(pl.col('campus') == 'idaho')[var][0]
170
+ hi_hi = kpi_max.filter(pl.col('campus') == 'hawaii')[var][0]
171
+
172
+
173
+ kpi_low = temp_box.select([var, 'campus']).group_by('campus').min()
174
+ pr_lo = kpi_low.filter(pl.col('campus') == 'provo')[var][0]
175
+ id_lo = kpi_low.filter(pl.col('campus') == 'idaho')[var][0]
176
+ hi_lo = kpi_low.filter(pl.col('campus') == 'hawaii')[var][0]
177
+
178
+
179
+ st.sidebar.altair_chart(daily)
180
+
181
+ columns[1].altair_chart(hourly_box)
182
+
183
+ columns[0].altair_chart(hourly_average)
184
+
185
+ with columns [2]:
186
+ sub_cols = st.columns(2)
187
+ with sub_cols[0]:
188
+ st.markdown(f"Provo Max: {round(pr_hi, 1)}")
189
+ st.markdown(f"Hawaii Max: {round(hi_hi, 1)}")
190
+ st.markdown(f"Idaho Max: {round(id_hi, 1)}")
191
+
192
+ with sub_cols[1]:
193
+ st.markdown(f"Provo Min: {round(pr_lo, 1)}")
194
+ st.markdown(f"Hawaii Min: {round(hi_lo, 1)}")
195
+ st.markdown(f"Idaho Min: {round(id_lo, 1)}")