Alex_Weather_App / streamlit.py
AlexNiel5261's picture
Rename streamlit_app.py to streamlit.py
5a3e3f0 verified
from collections import namedtuple
import altair as alt
import math
import pandas as pd
import streamlit as st
import polars as pl
import openmeteo_requests
from datetime import *
st.set_page_config(
page_title="Weather Data",
page_icon="🌤️",
layout='wide'
)
st.markdown("# Historic Weather Data for 3 BYU Campuses")
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.__")
columns = st.columns(3, gap='medium')
openmeteo = openmeteo_requests.Client()
st.sidebar.markdown("_Note: Data is only present up to 4 days ago_")
length = st.sidebar.slider("Length of Time Period for Data (Days)", min_value=5, max_value=30, value=15)
campus = ['provo', 'hawaii', 'idaho']
locations = [(40.2518, 111.6493), (21.6419, 157.9267), (43.8145, 111.7833)]
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))))
end = (start_day + timedelta(days=length)).strftime('%Y-%m-%d')
start = start_day.strftime('%Y-%m-%d')
zone_select = st.sidebar.selectbox("Choose Timezone", options=['Mountain Time', 'Hawaiian Time'])
zone = 'HST' if zone_select == 'Hawaiian Time' else 'MST'
variables = ['Temperature (F)', 'Apparent Temp (F)', 'Humidity (%)', 'Pressure (hPa)', 'Precipitation (in)', 'Rain (in)', 'Snowfall (in)', 'Cloud Cover (%)', 'Wind Speed (mph)', 'Snow Depth (m)']
variable_select = st.sidebar.selectbox("Choose variable of interest", options=variables)
variable_dict = {
'Temperature (F)': 'temperature_2m',
'Apparent Temp (F)': 'apparent_temperature',
'Humidity (%)': 'relative_humidity_2m',
'Pressure (hPa)': 'surface_pressure',
'Precipitation (in)': 'precipitation',
'Rain (in)': 'rain',
'Snowfall (in)': 'snowfall',
'Cloud Cover (%)': 'cloud_cover',
'Wind Speed (mph)': 'wind_speed_10m',
'Snow Depth (m)': 'snow_depth'
}
var = variable_dict[variable_select]
hi_lo = st.sidebar.selectbox("Daily Extremes", options=['Max', 'Min'])
daily_var = 'temperature_2m_max' if hi_lo == 'Max' else 'temperature_2m_min'
def request(url, lat, long, start, end, variable, time_unit, timezone):
params = {
"latitude": lat,
"longitude": long,
"start_date": start,
"end_date": end,
time_unit: variable,
"temperature_unit": "fahrenheit",
'timezone': timezone,
'precipitation_unit': 'inch',
'wind_speed_unit': 'mph'
}
return openmeteo.weather_api(url, params=params)[0]
i = 0
temp_box = pl.DataFrame()
for location in locations:
actual = request("https://archive-api.open-meteo.com/v1/archive", location[0], location[1], start, end, var, 'hourly', zone)
forecasted = request("https://historical-forecast-api.open-meteo.com/v1/forecast", location[0], location[1], start, end, var, 'hourly', zone)
hourly_actual= actual.Hourly()
hourly_var_actual = hourly_actual.Variables(0).ValuesAsNumpy()
hourly_forecasted = forecasted.Hourly()
hourly_var_forecasted = hourly_forecasted.Variables(0).ValuesAsNumpy()
hourly_data = {"date-time": pd.date_range(
start = pd.to_datetime(hourly_actual.Time(), unit = "s", utc = True),
end = pd.to_datetime(hourly_actual.TimeEnd(), unit = "s", utc = True),
freq = pd.Timedelta(seconds = hourly_actual.Interval()),
inclusive = "left"
)}
hourly_data[var] = hourly_var_actual
hourly_data[f"forecast_{var}"] = hourly_var_forecasted
hourly_dataframe = pl.DataFrame(hourly_data)
hourly_dataframe = hourly_dataframe.with_columns(pl.col('date-time').dt.strftime('%Y-%m-%d').alias('date'))
hourly_dataframe = hourly_dataframe.with_columns(pl.col('date-time').dt.strftime("%H:%M:%S").alias('time'))
with columns[i]:
st.markdown(f"### {campus[i].title()}")
st.dataframe(hourly_dataframe.drop('date-time'))
st.dataframe(hourly_dataframe.select([var, f'forecast_{var}']).describe()[2:9])
current_campus = hourly_dataframe.with_columns(pl.lit(campus[i]).alias('campus'))
end_month = (datetime.today() - timedelta(days=4)).strftime('%Y-%m-%d')
start_month = (datetime.today() - timedelta(days=35)).strftime('%Y-%m-%d')
daily = request("https://archive-api.open-meteo.com/v1/archive", location[0], location[1], start_month, end_month, daily_var, 'daily', zone).Daily()
daily_data = {"date-time": pd.date_range(
start = pd.to_datetime(daily.Time(), unit = "s", utc = True),
end = pd.to_datetime(daily.TimeEnd(), unit = "s", utc = True),
freq = pd.Timedelta(seconds = daily.Interval()),
inclusive = "left"
)}
daily_data['temperature'] = daily.Variables(0).ValuesAsNumpy()
daily_df = pl.DataFrame(daily_data)
daily_df = daily_df.with_columns(pl.lit(campus[i]).alias('campus'))
if len(temp_box) == 0:
temp_box = pl.DataFrame(current_campus)
temp_line = daily_df
else:
temp_box = temp_box.vstack(current_campus)
temp_line = temp_line.vstack(daily_df)
i+=1
daily = alt.Chart(temp_line).mark_line().encode(
alt.X("date-time"),
alt.Y('temperature'),
color='campus'
).properties(
title='Daily Temp Extremes Over Last Month',
width=300,
height=300
)
hourly_box = alt.Chart(temp_box).mark_boxplot().encode(
alt.X(var).scale(zero=False),
alt.Y("campus")
).properties(
title='Hourly Readings',
width=400,
height=300
)
grouped = temp_box.select(['time', var, 'campus']).group_by(['time', 'campus']).mean()
hourly_average = alt.Chart(grouped).mark_line().encode(
x="time",
y=var,
color="campus"
).properties(
title='Average Reading Given Time of Day',
width=400,
height=300
)
kpi_max = temp_box.select([var, 'campus']).group_by('campus').max()
pr_hi = kpi_max.filter(pl.col('campus') == 'provo')[var][0]
id_hi = kpi_max.filter(pl.col('campus') == 'idaho')[var][0]
hi_hi = kpi_max.filter(pl.col('campus') == 'hawaii')[var][0]
kpi_low = temp_box.select([var, 'campus']).group_by('campus').min()
pr_lo = kpi_low.filter(pl.col('campus') == 'provo')[var][0]
id_lo = kpi_low.filter(pl.col('campus') == 'idaho')[var][0]
hi_lo = kpi_low.filter(pl.col('campus') == 'hawaii')[var][0]
st.sidebar.altair_chart(daily)
columns[1].altair_chart(hourly_box)
columns[0].altair_chart(hourly_average)
with columns [2]:
sub_cols = st.columns(2)
with sub_cols[0]:
st.markdown(f"Provo Max: {round(pr_hi, 1)}")
st.markdown(f"Hawaii Max: {round(hi_hi, 1)}")
st.markdown(f"Idaho Max: {round(id_hi, 1)}")
with sub_cols[1]:
st.markdown(f"Provo Min: {round(pr_lo, 1)}")
st.markdown(f"Hawaii Min: {round(hi_lo, 1)}")
st.markdown(f"Idaho Min: {round(id_lo, 1)}")