euler314 commited on
Commit
dd02776
·
verified ·
1 Parent(s): 4114999

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +126 -0
app.py CHANGED
@@ -205,7 +205,133 @@ class TyphoonAnalyzer:
205
  finally:
206
  if os.path.exists(temp_file):
207
  os.remove(temp_file)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
208
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
209
  def convert_oni_ascii_to_csv(self, input_file, output_file):
210
  data = defaultdict(lambda: [''] * 12)
211
  season_to_month = {
 
205
  finally:
206
  if os.path.exists(temp_file):
207
  os.remove(temp_file)
208
+ def create_wind_analysis(self, data):
209
+ """Create wind speed analysis plot"""
210
+ fig = px.scatter(data,
211
+ x='ONI',
212
+ y='USA_WIND',
213
+ color='Category',
214
+ color_discrete_map=COLOR_MAP,
215
+ title='Wind Speed vs ONI Index',
216
+ labels={
217
+ 'ONI': 'Oceanic Niño Index',
218
+ 'USA_WIND': 'Maximum Wind Speed (kt)'
219
+ },
220
+ hover_data=['NAME', 'ISO_TIME', 'Category']
221
+ )
222
+
223
+ # Add regression line
224
+ x = data['ONI']
225
+ y = data['USA_WIND']
226
+ slope, intercept = np.polyfit(x, y, 1)
227
+ fig.add_trace(
228
+ go.Scatter(
229
+ x=x,
230
+ y=slope * x + intercept,
231
+ mode='lines',
232
+ name=f'Regression (slope={slope:.2f})',
233
+ line=dict(color='black', dash='dash')
234
+ )
235
+ )
236
+
237
+ return fig
238
+ def create_typhoon_animation(self, year, typhoon_id):
239
+ """Create animated visualization of typhoon path"""
240
+ if not typhoon_id:
241
+ return go.Figure(), "Please select a typhoon"
242
+
243
+ storm_data = self.typhoon_data[self.typhoon_data['SID'] == typhoon_id]
244
+ if storm_data.empty:
245
+ return go.Figure(), "No data available for selected typhoon"
246
+
247
+ storm_data = storm_data.sort_values('ISO_TIME')
248
+
249
+ fig = go.Figure()
250
+
251
+ # Base map settings
252
+ fig.update_layout(
253
+ title=f"Typhoon Path Animation - {storm_data['NAME'].iloc[0]}",
254
+ showlegend=True,
255
+ geo=dict(
256
+ projection_type='mercator',
257
+ showland=True,
258
+ showcoastlines=True,
259
+ landcolor='rgb(243, 243, 243)',
260
+ countrycolor='rgb(204, 204, 204)',
261
+ coastlinecolor='rgb(214, 214, 214)',
262
+ showocean=True,
263
+ oceancolor='rgb(230, 250, 255)',
264
+ lataxis=dict(range=[0, 50]),
265
+ lonaxis=dict(range=[100, 180]),
266
+ center=dict(lat=20, lon=140)
267
+ )
268
+ )
269
+
270
+ # Create animation frames
271
+ frames = []
272
+ for i in range(len(storm_data)):
273
+ frame = go.Frame(
274
+ data=[
275
+ go.Scattergeo(
276
+ lon=storm_data['LON'].iloc[:i+1],
277
+ lat=storm_data['LAT'].iloc[:i+1],
278
+ mode='lines+markers',
279
+ line=dict(width=2, color='red'),
280
+ marker=dict(size=8, color='red'),
281
+ name='Path',
282
+ hovertemplate=(
283
+ f"Time: {storm_data['ISO_TIME'].iloc[i]:%Y-%m-%d %H:%M}<br>" +
284
+ f"Wind: {storm_data['USA_WIND'].iloc[i]:.1f} kt<br>" +
285
+ f"Pressure: {storm_data['WMO_PRES'].iloc[i]:.1f} hPa<br>" +
286
+ f"Lat: {storm_data['LAT'].iloc[i]:.2f}°N<br>" +
287
+ f"Lon: {storm_data['LON'].iloc[i]:.2f}°E"
288
+ )
289
+ )
290
+ ],
291
+ name=f'frame{i}'
292
+ )
293
+ frames.append(frame)
294
 
295
+ fig.frames = frames
296
+
297
+ # Add animation controls
298
+ fig.update_layout(
299
+ updatemenus=[{
300
+ 'buttons': [
301
+ {
302
+ 'args': [None, {'frame': {'duration': 100, 'redraw': True},
303
+ 'fromcurrent': True}],
304
+ 'label': 'Play',
305
+ 'method': 'animate'
306
+ },
307
+ {
308
+ 'args': [[None], {'frame': {'duration': 0, 'redraw': True},
309
+ 'mode': 'immediate',
310
+ 'transition': {'duration': 0}}],
311
+ 'label': 'Pause',
312
+ 'method': 'animate'
313
+ }
314
+ ],
315
+ 'type': 'buttons',
316
+ 'showactive': False,
317
+ 'x': 0.1,
318
+ 'y': 0,
319
+ 'xanchor': 'right',
320
+ 'yanchor': 'top'
321
+ }]
322
+ )
323
+
324
+ info_text = f"""
325
+ ### Typhoon Information
326
+ - Name: {storm_data['NAME'].iloc[0]}
327
+ - Start Date: {storm_data['ISO_TIME'].iloc[0]:%Y-%m-%d %H:%M}
328
+ - End Date: {storm_data['ISO_TIME'].iloc[-1]:%Y-%m-%d %H:%M}
329
+ - Maximum Wind Speed: {storm_data['USA_WIND'].max():.1f} kt
330
+ - Minimum Pressure: {storm_data['WMO_PRES'].min():.1f} hPa
331
+ """
332
+
333
+ return fig, info_text
334
+
335
  def convert_oni_ascii_to_csv(self, input_file, output_file):
336
  data = defaultdict(lambda: [''] * 12)
337
  season_to_month = {