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") | |