Spaces:
Runtime error
Runtime error
import openmeteo_requests | |
import requests_cache | |
import polars as pl | |
from retry_requests import retry | |
import streamlit as st | |
from datetime import datetime, timedelta | |
import pytz | |
from lets_plot import * | |
from streamlit_letsplot import st_letsplot | |
import numpy as np | |
#API Fetch | |
openmeteo = openmeteo_requests.Client() | |
#Empty Frames | |
locations = [ | |
{"name": "Rexburg, Idaho", "latitude": 43.8251, "longitude": -111.7924}, | |
{"name": "Provo, Utah", "latitude": 40.2338, "longitude": -111.6585}, | |
{"name": "Laie, Hawaii", "latitude": 21.6210, "longitude": -157.9753} | |
] | |
location_names = [location["name"] for location in locations] | |
filtered_forecasts = {} | |
filtered_histories = {} | |
historical_data = [] | |
forecast_data = [] | |
timezones = pytz.all_timezones | |
def find_max(df): | |
daily_highs = df.group_by(by = 'Date').agg(pl.max("Temperature").alias('max')) | |
return daily_highs, df | |
# Date Variables | |
today = datetime.today() | |
default = today - timedelta(days=14) | |
# Streamlit Variables | |
start_date = st.sidebar.date_input( | |
'Select start date:', | |
value = default, | |
max_value= default | |
) | |
selected_timezone = st.sidebar.selectbox( | |
'Choose a timezone:', | |
timezones | |
) | |
end_date = start_date + timedelta(days=14) | |
temperature_option = st.sidebar.selectbox( | |
'Select Temperature Type', | |
('Highest', 'Lowest') | |
) | |
city_option = st.sidebar.selectbox( | |
'Select City', | |
('Rexburg, Idaho', 'Provo, Utah', 'Laie, Hawaii') | |
) | |
# Display the selected date range | |
st.sidebar.write(f"Date Range: {start_date} to {end_date}") | |
# Get Forecast Data | |
for location in locations: | |
url = "https://api.open-meteo.com/v1/forecast" | |
params = { | |
"latitude": location["latitude"], | |
"longitude": location["longitude"], | |
"start_date": start_date.strftime('%Y-%m-%d'), | |
"end_date": end_date.strftime('%Y-%m-%d'), | |
"hourly": "temperature_2m" | |
} | |
# Fetch weather data | |
responses = openmeteo.weather_api(url, params=params) | |
response = responses[0] | |
hourly = response.Hourly() | |
hourly_temperature_2m = hourly.Variables(0).ValuesAsNumpy() | |
# Convert timestamp to datetime | |
start = datetime.fromtimestamp(hourly.Time()) | |
end = datetime.fromtimestamp(hourly.TimeEnd()) | |
freq = timedelta(seconds=hourly.Interval()) | |
# Create Polars DataFrame | |
hourly_data = pl.select( | |
date = pl.datetime_range(start, end, freq, closed = "left"), | |
temperature_2m = hourly_temperature_2m, | |
location = [location["name"]]) | |
hourly_dataframe = pl.DataFrame(data = hourly_data) | |
historical_data.append(hourly_dataframe) | |
# Concatenate all DataFrames | |
combined_historical = pl.DataFrame(pl.concat(historical_data)).explode('location') | |
# Get True Historical Data | |
for location in locations: | |
url = "https://archive-api.open-meteo.com/v1/archive" | |
params = { | |
"latitude": location["latitude"], | |
"longitude": location["longitude"], | |
"start_date": start_date.strftime('%Y-%m-%d'), | |
"end_date": end_date.strftime('%Y-%m-%d'), | |
"hourly": "temperature_2m" | |
} | |
# Fetch weather data | |
responses = openmeteo.weather_api(url, params=params) | |
response = responses[0] | |
hourly = response.Hourly() | |
hourly_temperature_2m = hourly.Variables(0).ValuesAsNumpy() | |
# Convert timestamp to datetime | |
start = datetime.fromtimestamp(hourly.Time()) | |
end = datetime.fromtimestamp(hourly.TimeEnd()) | |
freq = timedelta(seconds=hourly.Interval()) | |
# Create Polars DataFrame | |
hourly_data = pl.select( | |
date = pl.datetime_range(start, end, freq, closed = "left"), | |
temperature_2m = hourly_temperature_2m, | |
location = [location["name"]]) | |
hourly_dataframe = pl.DataFrame(data = hourly_data) | |
forecast_data.append(hourly_dataframe) | |
combined_forecast = pl.DataFrame(pl.concat(forecast_data)).explode('location') | |
for name in location_names: | |
filtered_forecasts[name] = (combined_forecast.filter(pl.col("location") == name).drop('location').rename({'date': 'Date'}).rename({'temperature_2m': 'Temperature'}).with_columns(pl.col('Temperature') * 9/5 + 32)) | |
filtered_histories[name] = (combined_historical.filter(pl.col("location") == name).drop('location').rename({'date': 'Date'}).rename({'temperature_2m': 'Temperature'}).with_columns(pl.col('Temperature') * 9/5 + 32)) | |
tab1, tab2, tab3 = st.tabs(["Data", "Visualisations", "KPIs"]) | |
with tab1: | |
st.title("Forecasted Weather vs Actual Weather by City") | |
st.header('Forecasts') | |
st.markdown("<h2 style='text-align: center; color: white;'>Rexburg</h2>", unsafe_allow_html=True) | |
# Create two columns for Rexburg content | |
rexburg_col1, rexburg_col2 = st.columns(2) | |
# Rexburg content | |
with rexburg_col1: | |
st.write("Forecasts") | |
st.dataframe(filtered_forecasts["Rexburg, Idaho"], use_container_width=True, hide_index=True) | |
with rexburg_col2: | |
st.write("Historical Data") | |
st.dataframe(filtered_histories["Rexburg, Idaho"], use_container_width=True, hide_index=True) | |
# Provo Header | |
st.markdown("<h2 style='text-align: center; color: white;'>Provo</h2>", unsafe_allow_html=True) | |
# Create two columns for Provo content | |
provo_col1, provo_col2 = st.columns(2) | |
# Provo content | |
with provo_col1: | |
st.write("Forecasts") | |
st.dataframe(filtered_forecasts["Provo, Utah"], use_container_width=True, hide_index=True) | |
with provo_col2: | |
st.write("Historical Data") | |
st.dataframe(filtered_histories["Provo, Utah"], use_container_width=True, hide_index=True) | |
# Laie Header | |
st.markdown("<h2 style='text-align: center; color: white;'>Laie</h2>", unsafe_allow_html=True) | |
# Create two columns for Laie content | |
laie_col1, laie_col2 = st.columns(2) | |
# Laie content | |
with laie_col1: | |
st.write("Forecasts") | |
st.dataframe(filtered_forecasts["Laie, Hawaii"], use_container_width=True, hide_index=True) | |
with laie_col2: | |
st.write("Historical Data") | |
st.dataframe(filtered_histories["Laie, Hawaii"], use_container_width=True, hide_index=True) | |
with tab2: | |
st.header('Visualisations by City') | |
st.subheader("Forecasted Data vs. Historical Data") | |
combined_forecast = combined_forecast.rename({'date': 'Date'}).rename({'temperature_2m': 'Temperature'}).with_columns(pl.col('Temperature') * 9/5 + 32).with_columns(pl.col('Date').cast(datetime)) | |
combined_historical = combined_historical.rename({'date': 'Date'}).rename({'temperature_2m': 'Temperature'}).with_columns(pl.col('Temperature') * 9/5 + 32).with_columns(pl.col('Date').cast(datetime)) | |
reg_forecasted = ggplot(combined_forecast, aes(x='Date', y='Temperature', color = 'location')) \ | |
+ geom_line() \ | |
+ facet_wrap('location', ncol = 1) \ | |
+ labs(title = f'Hourly Temperatures', | |
x = 'Date', y = 'Temperature (°F)', color = 'City Name') + \ | |
guides(color="none") + \ | |
scale_x_datetime(format = '%m/%d') | |
reg_historical = ggplot(combined_historical, aes(x='Date', y='Temperature', color = 'location')) \ | |
+ geom_line() \ | |
+ facet_wrap('location', ncol = 1) \ | |
+ labs(title = f'Hourly Temperatures', | |
x = 'Date', y = 'Temperature (°F)', color = 'City Name') + \ | |
guides(color="none") + \ | |
scale_x_datetime(format = '%m/%d') | |
st.subheader('Forecasted') | |
st_letsplot(reg_forecasted) | |
st.subheader('Historical') | |
st_letsplot(reg_historical) | |
st.subheader('Boxplot of Average Hourly Temperature') | |
box_plot = ggplot(combined_forecast, aes(x='location', y='Temperature', color = 'location')) + \ | |
geom_jitter(alpha = .65) + \ | |
geom_boxplot(alpha = .9) + \ | |
labs(title=f'Hourly Temperature Readings', | |
x='City', y='Temperature (°F)') + \ | |
guides(color = "none") | |
st_letsplot(box_plot) | |
maxes = combined_historical.group_by('location').agg((pl.col('Temperature').max())) | |
max_plot = ggplot(maxes, aes(x = 'location', y = 'Temperature', color = 'location')) + \ | |
geom_bar(stat='identity') + \ | |
labs(x = 'City Name', y = 'Max Temperature in Month (°F)') | |
st.subheader('Maximum Temperature for Period') | |
st_letsplot(max_plot) | |
with tab3: | |
if temperature_option == 'Highest': | |
highest_temp = combined_historical.filter(pl.col('location') == city_option).select(pl.max('Temperature')).item() | |
st.metric(label=f"Highest Temperature in {city_option}", value=f"{round(highest_temp,2)} °F") | |
else: | |
# Get the lowest temperature and its corresponding date | |
lowest_temp = combined_historical.filter(pl.col('location') == city_option).select(pl.min('Temperature')).item() | |
st.metric(label=f"Highest Temperature in {city_option}", value=f"{round(lowest_temp,2)} °F") | |