File size: 5,024 Bytes
762f676 f64fe55 762f676 f64fe55 762f676 f64fe55 762f676 f64fe55 762f676 f64fe55 762f676 f64fe55 762f676 f64fe55 762f676 f64fe55 762f676 f64fe55 762f676 f64fe55 762f676 f64fe55 762f676 f64fe55 762f676 f64fe55 762f676 f64fe55 762f676 f64fe55 762f676 f64fe55 762f676 f64fe55 762f676 f64fe55 762f676 f64fe55 762f676 f64fe55 762f676 | 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 | # app.py
import pandas as pd
import numpy as np
import plotly.express as px
import plotly.graph_objects as go
import gradio as gr
from datetime import datetime
# Constants - Updated for NASA's new format
NASA_DATA_URL = "https://data.giss.nasa.gov/gistemp/tabledata_v4/GLB.Ts+dSST.csv"
CURRENT_YEAR = datetime.now().year
MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
def load_and_process_data():
"""Load and process NASA temperature data with updated format handling"""
try:
# Read NASA data with updated parameters
df = pd.read_csv(
NASA_DATA_URL,
skiprows=1,
na_values=['***', '****', '*****', '******'],
engine='python'
)
# Clean and reshape data - handle new column format
df = df[df['Year'] >= 1880]
# Select only year and month columns (new format uses month names)
df = df[['Year'] + MONTHS]
# Melt to long format using month names
df = df.melt(
id_vars='Year',
var_name='Month',
value_name='Anomaly'
)
# Convert month names to numeric values
month_map = {name: f"{i:02d}" for i, name in enumerate(MONTHS, 1)}
df['Month_Num'] = df['Month'].map(month_map)
# Create date column
df['Date'] = pd.to_datetime(
df['Year'].astype(str) + '-' + df['Month_Num'],
format='%Y-%m'
)
# Clean and process anomalies
df = df.dropna(subset=['Anomaly'])
df['Anomaly'] = df['Anomaly'].astype(float)
df['Decade'] = (df['Year'] // 10) * 10
# Calculate rolling averages
df = df.sort_values('Date')
df['5yr_avg'] = df['Anomaly'].rolling(60, min_periods=1).mean()
df['10yr_avg'] = df['Anomaly'].rolling(120, min_periods=1).mean()
return df
except Exception as e:
print(f"Data loading error: {e}")
return pd.DataFrame()
# ... [rest of visualization functions remain unchanged] ...
def create_dashboard():
"""Create Gradio dashboard with fixed components"""
df = load_and_process_data()
with gr.Blocks(title="NASA Climate Viz", theme=gr.themes.Soft()) as demo:
gr.Markdown("# 🌍 Earth's Surface Temperature Analysis")
# ... [header remains unchanged] ...
with gr.Tab("Time Series Analysis"):
gr.Markdown("## Global Temperature Anomalies Over Time")
with gr.Row():
show_uncertainty = gr.Checkbox(label="Show Uncertainty Bands")
# FIXED: Use new Slider syntax with range=True
year_range = gr.Slider(
minimum=1880,
maximum=CURRENT_YEAR,
value=[1950, CURRENT_YEAR],
label="Year Range",
step=1,
interactive=True,
range=True # This creates dual-handle range slider
)
time_series = gr.Plot()
with gr.Tab("Decadal Heatmap"):
gr.Markdown("## Monthly Anomalies by Decade")
# FIXED: Updated slider syntax
decade_range = gr.Slider(
minimum=1880,
maximum=CURRENT_YEAR - (CURRENT_YEAR % 10),
value=[1950, CURRENT_YEAR - (CURRENT_YEAR % 10)],
step=10,
label="Decade Range",
interactive=True,
range=True # Dual-handle range slider
)
heatmap = gr.Plot()
# ... [other tabs remain unchanged] ...
# Event handling with fixed input parameters
show_uncertainty.change(
fn=lambda u, y: create_time_series_plot(
df[(df['Year'] >= y[0]) & (df['Year'] <= y[1])],
u
),
inputs=[show_uncertainty, year_range],
outputs=time_series
)
year_range.input( # Use .input instead of .change for realtime updates
fn=lambda y, u: create_time_series_plot(
df[(df['Year'] >= y[0]) & (df['Year'] <= y[1])],
u
),
inputs=[year_range, show_uncertainty],
outputs=time_series
)
decade_range.input(
fn=lambda dr: create_heatmap(df, (dr[0], dr[1])),
inputs=decade_range,
outputs=heatmap
)
# Initial renders
demo.load(
fn=lambda: create_time_series_plot(df[(df['Year'] >= 1950) & (df['Year'] <= CURRENT_YEAR)]),
outputs=time_series
)
demo.load(
fn=lambda: create_heatmap(df, (1950, CURRENT_YEAR)),
outputs=heatmap
)
return demo
if __name__ == "__main__":
dashboard = create_dashboard()
dashboard.launch() |