File size: 5,400 Bytes
9529172 6936138 9529172 af33992 fc2f5b5 af33992 d804e71 af33992 d804e71 af33992 d804e71 af33992 d804e71 af33992 d804e71 af33992 d804e71 af33992 d804e71 af33992 d804e71 af33992 9529172 af33992 9529172 af33992 9529172 af33992 9529172 af33992 9529172 af33992 9529172 af33992 9529172 d804e71 9529172 af33992 9529172 af33992 9529172 af33992 9529172 af33992 9529172 af33992 9529172 af33992 d804e71 9529172 af33992 6936138 af33992 6936138 9529172 af33992 9529172 af33992 9529172 af33992 9529172 af33992 9529172 af33992 9529172 af33992 9529172 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
import streamlit as st
import pandas as pd
import plotly.express as px
import pydeck as pdk
# Set page layout and title
st.set_page_config(page_title="AI-Powered Air Quality Dashboard", layout="wide")
# CSS for custom styling
st.markdown("""
<style>
.card {
background-color: #ffffff;
padding: 20px;
border-radius: 15px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
margin-bottom: 20px;
}
.header {
font-size: 26px;
font-weight: bold;
color: #333333;
text-align: center;
margin-top: 10px;
margin-bottom: 20px;
}
.subheader {
font-size: 20px;
color: #555555;
font-weight: 600;
margin-top: 10px;
margin-bottom: 15px;
}
.recommendation {
background-color: #f0f9ff;
padding: 15px;
border-radius: 10px;
border-left: 5px solid #007bff;
color: #007bff;
font-weight: bold;
}
</style>
""", unsafe_allow_html=True)
# Sidebar for user interaction
st.sidebar.header("Air Quality Monitoring")
station_list = ["Louisville", "Lexington", "Richmond", "Elizabethtown"]
selected_station = st.sidebar.selectbox("Select AQI Station", station_list)
# Mock air quality data (can be replaced with real data)
aqi_data = {
"Louisville": {"AQI": 50, "Pollutant": "Carbon Monoxide", "CO_ppb": 572.21},
"Lexington": {"AQI": 150, "Pollutant": "Ozone", "O3_ppb": 70.00},
"Richmond": {"AQI": 400, "Pollutant": "PM2.5", "PM25_ug/m3": 180.00},
"Elizabethtown": {"AQI": 85, "Pollutant": "Sulfur Dioxide", "SO2_ppb": 15.00},
}
# Header
st.markdown("<div class='header'>AI-Powered Air Quality Dashboard</div>", unsafe_allow_html=True)
# Get selected station's data
station_data = aqi_data[selected_station]
# --- Cards Section ---
col1, col2, col3 = st.columns(3)
# Card 1: AQI Summary
with col1:
st.markdown("<div class='card'>", unsafe_allow_html=True)
st.metric(label="Air Quality Index (AQI)", value=station_data["AQI"])
st.write(f"**Top Pollutant:** {station_data['Pollutant']}")
st.write(f"**Concentration:** {station_data.get('CO_ppb', station_data.get('PM25_ug/m3', 'N/A'))} ppb/µg/m³")
st.markdown("</div>", unsafe_allow_html=True)
# Card 2: AI Recommendation
with col2:
st.markdown("<div class='card'>", unsafe_allow_html=True)
st.write("<div class='subheader'>AI Recommendation</div>", unsafe_allow_html=True)
# Generate recommendation based on AQI severity
if station_data["AQI"] <= 50:
recommendation = "The air quality is good. It's a great day to enjoy outdoor activities."
elif station_data["AQI"] <= 100:
recommendation = "The air quality is moderate. Sensitive groups may need to limit prolonged outdoor activities."
elif station_data["AQI"] <= 150:
recommendation = "Unhealthy for sensitive groups. Reduce outdoor exertion if you have heart or lung conditions."
else:
recommendation = "The air is hazardous. It's strongly recommended to stay indoors and use air purifiers."
st.markdown(f"<div class='recommendation'>{recommendation}</div>", unsafe_allow_html=True)
st.markdown("</div>", unsafe_allow_html=True)
# Card 3: Health Impact Insights
with col3:
st.markdown("<div class='card'>", unsafe_allow_html=True)
st.write("<div class='subheader'>Health Impact</div>", unsafe_allow_html=True)
st.write("""
- **General Population:** No immediate danger at low AQI levels.
- **Sensitive Groups:** Individuals with heart or lung conditions may experience symptoms at higher AQI.
""")
st.markdown("</div>", unsafe_allow_html=True)
# --- Trends Visualization ---
st.subheader("AQI Trends Over Time")
trend_data = pd.DataFrame({
"Date": ["2023-01-01", "2023-01-02", "2023-01-03", "2023-01-04"],
"AQI": [station_data["AQI"] - 20, station_data["AQI"], station_data["AQI"] + 30, station_data["AQI"] - 10]
})
trend_chart = px.line(trend_data, x="Date", y="AQI", title=f"AQI Trend for {selected_station}")
trend_chart.update_traces(line=dict(color="#007bff"))
trend_chart.update_layout(plot_bgcolor="rgba(0,0,0,0)", paper_bgcolor="rgba(0,0,0,0)")
st.plotly_chart(trend_chart, use_container_width=True)
# --- Map Section ---
st.subheader("Air Quality Stations Map")
map_data = pd.DataFrame(
[
{"lat": 38.2527, "lon": -85.7585, "AQI": 50}, # Louisville
{"lat": 38.0406, "lon": -84.5037, "AQI": 150}, # Lexington
{"lat": 37.7479, "lon": -84.2947, "AQI": 400}, # Richmond
{"lat": 37.6939, "lon": -85.8591, "AQI": 85}, # Elizabethtown
]
)
# Render the map with AQI points
aqi_map = pdk.Deck(
map_style="mapbox://styles/mapbox/light-v9",
initial_view_state=pdk.ViewState(
latitude=38.0,
longitude=-85.5,
zoom=7,
pitch=50,
),
layers=[
pdk.Layer(
"ScatterplotLayer",
data=map_data,
get_position="[lon, lat]",
get_radius=5000,
get_fill_color="[255-AQI, 100, AQI/2, 150]",
pickable=True,
)
],
)
st.pydeck_chart(aqi_map)
# --- Footer ---
st.write("---")
st.write("Learn more about air quality and its impact [here](https://www.epa.gov/air-quality-index).")
|