Spaces:
Running
Running
File size: 5,119 Bytes
4daf938 9e3edd6 4daf938 6d148cf b0c4c5c 4daf938 6d148cf 9e3edd6 6d148cf d893665 9e3edd6 d893665 6d148cf 4daf938 6d148cf 4daf938 6d148cf 4daf938 6d148cf b0c4c5c 4daf938 6d148cf 9e3edd6 6d148cf 32a1a86 4daf938 6d148cf 9e3edd6 6d148cf 4daf938 6d148cf b0c4c5c 9e3edd6 6d148cf 32a1a86 6d148cf b0c4c5c 6d148cf b0c4c5c 4daf938 6d148cf 4daf938 6d148cf 9e3edd6 6d148cf b0c4c5c 4daf938 b0c4c5c 6d148cf 4daf938 6d148cf 4daf938 5c643e0 | 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 153 154 155 156 157 158 | import streamlit as st
import pandas as pd
import altair as alt
import json
import os
from datetime import datetime
# -------------------------------
# App Config and Title
# -------------------------------
st.set_page_config(page_title="Đài Quan sát Đồng hồ Khí hậu", layout="wide")
st.title("🌍 Đài Quan sát Đồng hồ Khí hậu Thời gian Thực")
# -------------------------------
# Show Last Updated Timestamp
# -------------------------------
try:
file_stats = os.stat("climate_data.json")
last_updated = datetime.fromtimestamp(file_stats.st_mtime).strftime("%Y-%m-%d %H:%M:%S")
st.caption(f"🕒 Data last updated: {last_updated}")
except:
st.caption("🕒 Last updated time not available")
# -------------------------------
# Refresh Button
# -------------------------------
if st.button("🔁 Refresh Data"):
with st.spinner("Refreshing data..."):
st.experimental_rerun()
# -------------------------------
# Load Climate Data from JSON
# -------------------------------
try:
with open("climate_data.json", "r") as f:
clock = json.load(f)
except Exception as e:
st.error("❌ Failed to load climate data.")
st.stop()
# -------------------------------
# 1️⃣ CO₂ Budget Depletion Projection
# -------------------------------
st.header("1️⃣ Dự báo Cạn kiệt Ngân quỹ CO₂ ")
co2_data = clock.get("co2", {})
co2_remaining = float(co2_data.get("remaining", 0))
co2_rate = float(co2_data.get("rate", 0))
years = list(range(datetime.now().year, datetime.now().year + 10))
remaining_budget = [max(co2_remaining - i * co2_rate, 0) for i in range(10)]
co2_df = pd.DataFrame({"Year": years, "Remaining CO₂ Budget (Gt)": remaining_budget})
co2_chart = alt.Chart(co2_df).mark_line(point=True).encode(
x='Year:O',
y='Remaining CO₂ Budget (Gt):Q',
tooltip=['Year', 'Remaining CO₂ Budget (Gt)']
).properties(width=700)
st.altair_chart(co2_chart, use_container_width=True)
# -------------------------------
# 2️⃣ Global Energy Mix Donut Chart
# -------------------------------
st.header("2️⃣ Tổng hợp Năng lượng Toàn cầu – Năng lượng tái tạo vs Các loại khác")
renew_data = clock.get("renewables", {})
renew_percent = float(renew_data.get("percentage", 0))
energy_df = pd.DataFrame({
"Type": ["Renewables", "Other"],
"Percentage": [renew_percent, 100 - renew_percent]
})
energy_chart = alt.Chart(energy_df).mark_arc(innerRadius=50).encode(
theta="Percentage:Q",
color="Type:N",
tooltip=["Type", "Percentage"]
).properties(width=400, height=400)
st.altair_chart(energy_chart, use_container_width=True)
# -------------------------------
# 3️⃣ Lifeline Metrics Bar Chart
# -------------------------------
st.header("3️⃣ Chỉ số Lifeline – Những đóng góp tích cực")
lifelines = clock.get("lifelines", [])
lifeline_df = pd.DataFrame([
{"Label": item.get("label", ""), "Value": float(item.get("value", 0))}
for item in lifelines
])
lifeline_chart = alt.Chart(lifeline_df).mark_bar().encode(
x=alt.X("Label:N", sort="-y"),
y="Value:Q",
tooltip=["Label", "Value"]
).properties(width=700)
st.altair_chart(lifeline_chart, use_container_width=True)
# -------------------------------
# 4️⃣ Time Left to 1.5°C Threshold
# -------------------------------
st.header("4️⃣ Thời gian còn lại đến ngưỡng 1.5°C ")
deadline = clock.get("deadline", {})
time_parts = deadline.get("time_left", "0:0:0:0:0").split(":")
try:
years, months, days = int(time_parts[0]), int(time_parts[1]), int(time_parts[2])
st.success(f"⏳ Estimated time before 1.5°C threshold: {years} years, {months} months, {days} days")
except:
st.warning("⚠️ Could not parse climate deadline.")
# -------------------------------
# 5️⃣ CO₂ Budget Simulator with Slider
# -------------------------------
st.header("5️⃣ Mô phỏng Ngân quỹ CO₂ – Sẽ như thế nào nếu chúng ta giảm phát thải?")
st.markdown("📉 Sử dụng thanh trượt bên dưới để mô phỏng lượng khí thải hàng năm được giảm và hình dung tác động của nó.")
new_rate = st.slider(
"New Annual CO₂ Emission Rate (Gt/year)",
min_value=10.0,
max_value=45.0,
value=co2_rate,
step=0.5
)
sim_years = []
sim_budget = []
current_budget = co2_remaining
year = datetime.now().year
while current_budget > 0 and len(sim_years) < 20:
sim_years.append(year)
sim_budget.append(current_budget)
current_budget -= new_rate
year += 1
sim_df = pd.DataFrame({
"Year": sim_years,
"Projected CO₂ Budget (Gt)": sim_budget
})
sim_chart = alt.Chart(sim_df).mark_line(point=True).encode(
x="Year:O",
y="Projected CO₂ Budget (Gt):Q",
tooltip=["Year", "Projected CO₂ Budget (Gt)"]
).properties(width=700)
st.altair_chart(sim_chart, use_container_width=True)
# -------------------------------
# Footer
# -------------------------------
st.markdown("---")
st.caption("Built and Powered by Mạng lưới GXS | Data from Climate Clock API (cached sample)")
|