Files
shelly-ui/.agents/skills/developing-with-streamlit/templates/apps/dashboard-seattle-weather/streamlit_app.py
T
jonas 71803418e5 Initial commit: Shelly Manager with Textual CLI, Streamlit UI, and comprehensive .gitignore
Shelly device management app with mDNS/subnet discovery, inventory,
configuration, and mass operations for Gen1/Gen2+ devices.

Includes .gitignore excluding runtime data (device DB, user config),
AI conversation history, build artifacts, and common Python/OS patterns.
2026-03-23 21:51:59 +01:00

253 lines
6.4 KiB
Python

import streamlit as st
import altair as alt
import vega_datasets
full_df = vega_datasets.data("seattle_weather")
st.set_page_config(
# Title and icon for the browser's tab bar:
page_title="Seattle Weather",
page_icon=":mostly_sunny:",
# Make the content take up the width of the page:
layout="wide",
)
"""
# Seattle Weather
Let's explore the [classic Seattle Weather
dataset](https://altair-viz.github.io/case_studies/exploring-weather.html)!
"""
"" # Add a little vertical space. Same as st.write("").
""
"""
## 2015 Summary
"""
""
df_2015 = full_df[full_df["date"].dt.year == 2015]
df_2014 = full_df[full_df["date"].dt.year == 2014]
max_temp_2015 = df_2015["temp_max"].max()
max_temp_2014 = df_2014["temp_max"].max()
min_temp_2015 = df_2015["temp_min"].min()
min_temp_2014 = df_2014["temp_min"].min()
max_wind_2015 = df_2015["wind"].max()
max_wind_2014 = df_2014["wind"].max()
min_wind_2015 = df_2015["wind"].min()
min_wind_2014 = df_2014["wind"].min()
max_prec_2015 = df_2015["precipitation"].max()
max_prec_2014 = df_2014["precipitation"].max()
min_prec_2015 = df_2015["precipitation"].min()
min_prec_2014 = df_2014["precipitation"].min()
with st.container(horizontal=True, gap="medium"):
cols = st.columns(2, gap="medium", width=300)
with cols[0]:
st.metric(
"Max temperature",
f"{max_temp_2015:0.1f}C",
delta=f"{max_temp_2015 - max_temp_2014:0.1f}C",
width="content",
)
with cols[1]:
st.metric(
"Min temperature",
f"{min_temp_2015:0.1f}C",
delta=f"{min_temp_2015 - min_temp_2014:0.1f}C",
width="content",
)
cols = st.columns(2, gap="medium", width=300)
with cols[0]:
st.metric(
"Max precipitation",
f"{max_prec_2015:0.1f}mm",
delta=f"{max_prec_2015 - max_prec_2014:0.1f}mm",
width="content",
)
with cols[1]:
st.metric(
"Min precipitation",
f"{min_prec_2015:0.1f}mm",
delta=f"{min_prec_2015 - min_prec_2014:0.1f}mm",
width="content",
)
cols = st.columns(2, gap="medium", width=300)
with cols[0]:
st.metric(
"Max wind",
f"{max_wind_2015:0.1f}m/s",
delta=f"{max_wind_2015 - max_wind_2014:0.1f}m/s",
width="content",
)
with cols[1]:
st.metric(
"Min wind",
f"{min_wind_2015:0.1f}m/s",
delta=f"{min_wind_2015 - min_wind_2014:0.1f}m/s",
width="content",
)
weather_icons = {
"sun": "sunny",
"snow": "weather_snowy",
"rain": "rainy",
"fog": "foggy",
"drizzle": "rainy",
}
cols = st.columns(2, gap="large")
with cols[0]:
weather_name = (
full_df["weather"].value_counts().head(1).reset_index()["weather"][0]
)
st.metric(
"Most common weather",
f":material/{weather_icons[weather_name]}: {weather_name.upper()}",
)
with cols[1]:
weather_name = (
full_df["weather"].value_counts().tail(1).reset_index()["weather"][0]
)
st.metric(
"Least common weather",
f":material/{weather_icons[weather_name]}: {weather_name.upper()}",
)
""
""
"""
## Compare different years
"""
YEARS = full_df["date"].dt.year.unique()
selected_years = st.pills(
"Years to compare", YEARS, default=YEARS, selection_mode="multi"
)
if not selected_years:
st.warning("You must select at least 1 year.", icon=":material/warning:")
df = full_df[full_df["date"].dt.year.isin(selected_years)]
cols = st.columns([3, 1])
with cols[0].container(border=True, height="stretch"):
"### 🌡️ Temperature"
st.altair_chart(
alt.Chart(df)
.mark_bar(width=1)
.encode(
alt.X("monthdate(date):T").title("date"),
alt.Y("temp_max:Q").title("temperature range (C)"),
alt.Y2("temp_min:Q"),
alt.Color("year(date):N").title("year"),
alt.XOffset("year(date):N"),
tooltip=[
alt.Tooltip("monthdate(date):T", title="Date"),
alt.Tooltip("temp_max:Q", title="Max Temp (C)"),
alt.Tooltip("temp_min:Q", title="Min Temp (C)"),
alt.Tooltip("year(date):N", title="Year"),
],
)
.configure_legend(orient="bottom")
)
with cols[1].container(border=True, height="stretch"):
"### Weather distribution"
st.altair_chart(
alt.Chart(df)
.mark_arc()
.encode(
alt.Theta("count()"),
alt.Color("weather:N"),
)
.configure_legend(orient="bottom")
)
cols = st.columns(2)
with cols[0].container(border=True, height="stretch"):
"### 💨 Wind"
# Prepare data for st.line_chart - pivot by year
wind_df = df.copy()
wind_df["month_day"] = wind_df["date"].dt.strftime("%m-%d")
wind_df["year"] = wind_df["date"].dt.year
# Calculate 14-day rolling average per year
wind_pivot = wind_df.pivot_table(
index="month_day",
columns="year",
values="wind",
aggfunc="mean"
).sort_index()
st.line_chart(wind_pivot, height=300)
with cols[1].container(border=True, height="stretch"):
"### 🌧️ Precipitation"
st.altair_chart(
alt.Chart(df)
.mark_bar()
.encode(
alt.X("month(date):O").title("month"),
alt.Y("sum(precipitation):Q").title("precipitation (mm)"),
alt.Color("year(date):N").title("year"),
tooltip=[
alt.Tooltip("month(date):O", title="Month"),
alt.Tooltip("sum(precipitation):Q", title="Precipitation (mm)"),
alt.Tooltip("year(date):N", title="Year"),
],
)
.configure_legend(orient="bottom")
)
cols = st.columns(2)
with cols[0].container(border=True, height="stretch"):
"### Monthly weather breakdown"
""
st.altair_chart(
alt.Chart(df)
.mark_bar()
.encode(
alt.X("month(date):O", title="month"),
alt.Y("count():Q", title="days").stack("normalize"),
alt.Color("weather:N"),
)
.configure_legend(orient="bottom")
)
with cols[1].container(border=True, height="stretch"):
"### Raw data"
st.dataframe(df)