| | |
| | 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 |
| |
|
| | |
| | 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: |
| | |
| | df = pd.read_csv( |
| | NASA_DATA_URL, |
| | skiprows=1, |
| | na_values=['***', '****', '*****', '******'], |
| | engine='python' |
| | ) |
| | |
| | |
| | df = df[df['Year'] >= 1880] |
| | |
| | |
| | df = df[['Year'] + MONTHS] |
| | |
| | |
| | df = df.melt( |
| | id_vars='Year', |
| | var_name='Month', |
| | value_name='Anomaly' |
| | ) |
| | |
| | |
| | month_map = {name: f"{i:02d}" for i, name in enumerate(MONTHS, 1)} |
| | df['Month_Num'] = df['Month'].map(month_map) |
| | |
| | |
| | df['Date'] = pd.to_datetime( |
| | df['Year'].astype(str) + '-' + df['Month_Num'], |
| | format='%Y-%m' |
| | ) |
| | |
| | |
| | df = df.dropna(subset=['Anomaly']) |
| | df['Anomaly'] = df['Anomaly'].astype(float) |
| | df['Decade'] = (df['Year'] // 10) * 10 |
| | |
| | |
| | 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() |
| |
|
| | |
| |
|
| | 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") |
| | |
| | |
| | |
| | with gr.Tab("Time Series Analysis"): |
| | gr.Markdown("## Global Temperature Anomalies Over Time") |
| | with gr.Row(): |
| | show_uncertainty = gr.Checkbox(label="Show Uncertainty Bands") |
| | |
| | year_range = gr.Slider( |
| | minimum=1880, |
| | maximum=CURRENT_YEAR, |
| | value=[1950, CURRENT_YEAR], |
| | label="Year Range", |
| | step=1, |
| | interactive=True, |
| | range=True |
| | ) |
| | time_series = gr.Plot() |
| | |
| | with gr.Tab("Decadal Heatmap"): |
| | gr.Markdown("## Monthly Anomalies by Decade") |
| | |
| | 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 |
| | ) |
| | heatmap = gr.Plot() |
| | |
| | |
| | |
| | |
| | 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( |
| | 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 |
| | ) |
| | |
| | |
| | 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() |