Navya-Sree commited on
Commit
762f676
·
verified ·
1 Parent(s): 822e26b

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +327 -0
app.py ADDED
@@ -0,0 +1,327 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # app.py
2
+ import pandas as pd
3
+ import numpy as np
4
+ import plotly.express as px
5
+ import plotly.graph_objects as go
6
+ import plotly.subplots as sp
7
+ import gradio as gr
8
+ from datetime import datetime
9
+
10
+ # Constants
11
+ NASA_DATA_URL = "https://data.giss.nasa.gov/gistemp/tabledata_v4/GLB.Ts+dSST.csv"
12
+ CURRENT_YEAR = datetime.now().year
13
+
14
+ def load_and_process_data():
15
+ """Load and process NASA temperature data with robust error handling"""
16
+ try:
17
+ # Read NASA data with metadata handling
18
+ df = pd.read_csv(
19
+ NASA_DATA_URL,
20
+ skiprows=1,
21
+ na_values=['***', '****', '*****', '******']
22
+ )
23
+
24
+ # Clean and reshape data
25
+ df = df[df['Year'] >= 1880] # Reliable data starts from 1880
26
+ df = df[['Year'] + [str(m) for m in range(1,13)]]
27
+ df.columns = ['Year'] + [f"{i:02d}" for i in range(1,13)]
28
+
29
+ # Melt to long format and handle dates
30
+ df = df.melt(id_vars='Year', var_name='Month', value_name='Anomaly')
31
+ df['Date'] = pd.to_datetime(df['Year'].astype(str) + '-' + df['Month'], format='%Y-%m')
32
+ df = df.dropna(subset=['Anomaly'])
33
+ df['Anomaly'] = df['Anomaly'].astype(float)
34
+ df['Decade'] = (df['Year'] // 10) * 10
35
+
36
+ # Calculate rolling averages
37
+ df['5yr_avg'] = df['Anomaly'].rolling(60, min_periods=1).mean()
38
+ df['10yr_avg'] = df['Anomaly'].rolling(120, min_periods=1).mean()
39
+
40
+ return df
41
+
42
+ except Exception as e:
43
+ print(f"Data loading error: {e}")
44
+ return pd.DataFrame()
45
+
46
+ def create_time_series_plot(df, show_uncertainty=False):
47
+ """Create interactive time series plot with advanced features"""
48
+ if df.empty:
49
+ return go.Figure()
50
+
51
+ fig = go.Figure()
52
+
53
+ # Add monthly anomalies
54
+ fig.add_trace(go.Scatter(
55
+ x=df['Date'],
56
+ y=df['Anomaly'],
57
+ mode='markers',
58
+ marker=dict(size=3, opacity=0.3, color='lightgray'),
59
+ name='Monthly Anomaly'
60
+ ))
61
+
62
+ # Add trend lines
63
+ fig.add_trace(go.Scatter(
64
+ x=df['Date'],
65
+ y=df['5yr_avg'],
66
+ mode='lines',
67
+ line=dict(width=2, color='blue'),
68
+ name='5-Year Average'
69
+ ))
70
+
71
+ fig.add_trace(go.Scatter(
72
+ x=df['Date'],
73
+ y=df['10yr_avg'],
74
+ mode='lines',
75
+ line=dict(width=3, color='red'),
76
+ name='10-Year Average'
77
+ ))
78
+
79
+ # Add uncertainty bands if requested
80
+ if show_uncertainty:
81
+ rolling_std = df['Anomaly'].rolling(120).std()
82
+ fig.add_trace(go.Scatter(
83
+ x=df['Date'],
84
+ y=df['10yr_avg'] + rolling_std,
85
+ fill=None,
86
+ mode='lines',
87
+ line=dict(width=0),
88
+ showlegend=False
89
+ ))
90
+
91
+ fig.add_trace(go.Scatter(
92
+ x=df['Date'],
93
+ y=df['10yr_avg'] - rolling_std,
94
+ fill='tonexty',
95
+ mode='lines',
96
+ line=dict(width=0),
97
+ name='Uncertainty'
98
+ ))
99
+
100
+ # Add reference line at 0°C
101
+ fig.add_hline(y=0, line_dash="dash", line_color="black")
102
+
103
+ # Add significant warming markers
104
+ recent = df[df['Year'] >= 2000]
105
+ if not recent.empty:
106
+ fig.add_trace(go.Scatter(
107
+ x=recent['Date'],
108
+ y=recent['10yr_avg'],
109
+ mode='markers',
110
+ marker=dict(size=8, color='red'),
111
+ name='Post-2000 Average'
112
+ ))
113
+
114
+ # Layout enhancements
115
+ fig.update_layout(
116
+ title='Global Temperature Anomalies (1880-Present)',
117
+ xaxis_title='Year',
118
+ yaxis_title='Temperature Anomaly (°C)',
119
+ hovermode='x unified',
120
+ template='plotly_dark',
121
+ height=600,
122
+ annotations=[
123
+ dict(
124
+ x=0.01, y=0.01,
125
+ xref="paper", yref="paper",
126
+ text="Data Source: NASA GISS",
127
+ showarrow=False
128
+ )
129
+ ]
130
+ )
131
+
132
+ return fig
133
+
134
+ def create_heatmap(df, decade_range=(1950, CURRENT_YEAR)):
135
+ """Create decadal heatmap visualization"""
136
+ if df.empty:
137
+ return go.Figure()
138
+
139
+ # Filter and aggregate data
140
+ filtered = df[df['Decade'].between(decade_range[0], decade_range[1])]
141
+ if filtered.empty:
142
+ return go.Figure()
143
+
144
+ pivot_df = filtered.pivot_table(
145
+ index='Decade',
146
+ columns='Month',
147
+ values='Anomaly',
148
+ aggfunc='mean'
149
+ )
150
+
151
+ # Create heatmap
152
+ fig = px.imshow(
153
+ pivot_df,
154
+ labels=dict(x="Month", y="Decade", color="Anomaly"),
155
+ x=['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
156
+ 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
157
+ color_continuous_scale='RdBu_r',
158
+ aspect="auto"
159
+ )
160
+
161
+ # Add annotations
162
+ for i, row in enumerate(pivot_df.values):
163
+ for j, value in enumerate(row):
164
+ fig.add_annotation(
165
+ x=j, y=i,
166
+ text=f"{value:.1f}",
167
+ showarrow=False,
168
+ font=dict(color='black' if abs(value) < 0.8 else 'white')
169
+ )
170
+
171
+ # Layout enhancements
172
+ fig.update_layout(
173
+ title=f'Decadal Temperature Anomalies ({decade_range[0]}-{decade_range[1]})',
174
+ xaxis_title="",
175
+ yaxis_title="Decade",
176
+ coloraxis_colorbar=dict(title="Anomaly (°C)"),
177
+ height=600
178
+ )
179
+
180
+ return fig
181
+
182
+ def create_regional_comparison(df):
183
+ """Create regional comparison visualization (mock data)"""
184
+ # In a real implementation, this would use actual regional data
185
+ regions = {
186
+ 'Arctic': 2.5,
187
+ 'Global': 1.2,
188
+ 'Europe': 1.5,
189
+ 'Asia': 1.3,
190
+ 'North America': 1.4,
191
+ 'Africa': 1.1,
192
+ 'South America': 1.0,
193
+ 'Oceania': 1.1,
194
+ 'Antarctica': 0.8
195
+ }
196
+
197
+ fig = go.Figure(go.Bar(
198
+ x=list(regions.values()),
199
+ y=list(regions.keys()),
200
+ orientation='h',
201
+ marker_color='crimson'
202
+ ))
203
+
204
+ fig.update_layout(
205
+ title='Regional Warming Rates (Since Pre-Industrial)',
206
+ xaxis_title='Temperature Increase (°C)',
207
+ yaxis_title='Region',
208
+ template='plotly_dark',
209
+ height=500
210
+ )
211
+
212
+ return fig
213
+
214
+ def create_dashboard():
215
+ """Create Gradio dashboard with multiple visualizations"""
216
+ df = load_and_process_data()
217
+
218
+ with gr.Blocks(title="NASA Climate Viz", theme=gr.themes.Soft()) as demo:
219
+ gr.Markdown("# 🌍 Earth's Surface Temperature Analysis")
220
+ gr.Markdown("### Visualization of NASA's Global Temperature Data")
221
+
222
+ with gr.Row():
223
+ gr.Markdown("""
224
+ **Data Source**: [NASA Goddard Institute for Space Studies](https://data.giss.nasa.gov/gistemp/)
225
+ **Last Update**: {CURRENT_YEAR}
226
+ **Base Period**: 1951-1980
227
+ """)
228
+
229
+ with gr.Tab("Time Series Analysis"):
230
+ gr.Markdown("## Global Temperature Anomalies Over Time")
231
+ with gr.Row():
232
+ show_uncertainty = gr.Checkbox(label="Show Uncertainty Bands")
233
+ year_range = gr.RangeSlider(
234
+ minimum=1880,
235
+ maximum=CURRENT_YEAR,
236
+ value=[1950, CURRENT_YEAR],
237
+ label="Year Range"
238
+ )
239
+ time_series = gr.Plot()
240
+
241
+ with gr.Tab("Decadal Heatmap"):
242
+ gr.Markdown("## Monthly Anomalies by Decade")
243
+ decade_range = gr.RangeSlider(
244
+ minimum=1880,
245
+ maximum=CURRENT_YEAR - (CURRENT_YEAR % 10),
246
+ value=[1950, CURRENT_YEAR - (CURRENT_YEAR % 10)],
247
+ step=10,
248
+ label="Decade Range"
249
+ )
250
+ heatmap = gr.Plot()
251
+
252
+ with gr.Tab("Regional Comparison"):
253
+ gr.Markdown("## Regional Warming Patterns")
254
+ gr.Markdown("*Note: Regional data shown is for demonstration purposes*")
255
+ region_plot = gr.Plot()
256
+
257
+ with gr.Tab("Data Insights"):
258
+ gr.Markdown("## Key Climate Observations")
259
+ if not df.empty:
260
+ latest = df[df['Year'] == df['Year'].max()]
261
+ hottest_year = df.groupby('Year')['Anomaly'].mean().idxmax()
262
+ hottest_decade = df.groupby('Decade')['Anomaly'].mean().idxmax()
263
+
264
+ insights = f"""
265
+ - 📈 **Current Decade ({CURRENT_YEAR//10*10}s)**: {df[df['Decade'] == CURRENT_YEAR//10*10]['Anomaly'].mean():.2f}°C anomaly
266
+ - 🔥 **Hottest Year**: {hottest_year} ({df[df['Year'] == hottest_year]['Anomaly'].mean():.2f}°C)
267
+ - 🌡️ **Recent Temperature**: {latest['Anomaly'].mean():.2f}°C above baseline
268
+ - 📅 **Long-term Trend**: {df['Anomaly'].mean():.2f}°C average anomaly since 1880
269
+ - ⏱️ **Acceleration**: Warming rate has doubled since 1980
270
+ """
271
+ else:
272
+ insights = "Data not available"
273
+
274
+ gr.Markdown(insights)
275
+ gr.Markdown("### Temperature Change Since 1880")
276
+ if not df.empty:
277
+ change_df = df.groupby('Year').agg({'Anomaly': 'mean'}).reset_index()
278
+ change_df['Change'] = change_df['Anomaly'].cumsum()
279
+ change_plot = px.area(change_df, x='Year', y='Change')
280
+ gr.Plot(change_plot)
281
+
282
+ # Event handling
283
+ show_uncertainty.change(
284
+ fn=lambda u, y: create_time_series_plot(
285
+ df[(df['Year'] >= y[0]) & (df['Year'] <= y[1])],
286
+ u
287
+ ),
288
+ inputs=[show_uncertainty, year_range],
289
+ outputs=time_series
290
+ )
291
+
292
+ year_range.change(
293
+ fn=lambda y, u: create_time_series_plot(
294
+ df[(df['Year'] >= y[0]) & (df['Year'] <= y[1])],
295
+ u
296
+ ),
297
+ inputs=[year_range, show_uncertainty],
298
+ outputs=time_series
299
+ )
300
+
301
+ decade_range.change(
302
+ fn=lambda dr: create_heatmap(df, dr),
303
+ inputs=decade_range,
304
+ outputs=heatmap
305
+ )
306
+
307
+ # Initial renders
308
+ demo.load(
309
+ fn=lambda: create_time_series_plot(df[(df['Year'] >= 1950) & (df['Year'] <= CURRENT_YEAR)]),
310
+ outputs=time_series
311
+ )
312
+
313
+ demo.load(
314
+ fn=lambda: create_heatmap(df, [1950, CURRENT_YEAR]),
315
+ outputs=heatmap
316
+ )
317
+
318
+ demo.load(
319
+ fn=create_regional_comparison,
320
+ outputs=region_plot
321
+ )
322
+
323
+ return demo
324
+
325
+ if __name__ == "__main__":
326
+ dashboard = create_dashboard()
327
+ dashboard.launch()