euler314 commited on
Commit
1ad4a07
·
verified ·
1 Parent(s): a7a961a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +122 -7
app.py CHANGED
@@ -1236,9 +1236,64 @@ def create_genesis_animation(prediction_data, enable_animation=True):
1236
  intensities = [pt['intensity'] for pt in current_track]
1237
  categories = [pt['category'] for pt in current_track]
1238
 
1239
- # (…rest of historical track, current position, uncertainty cone, genesis marker…)
1240
- # identical to before, omitted for brevity
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1241
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1242
  # Create frame
1243
  frames.append(go.Frame(
1244
  data=frame_data,
@@ -1266,8 +1321,50 @@ def create_genesis_animation(prediction_data, enable_animation=True):
1266
 
1267
  fig.frames = frames
1268
 
1269
- # Set up initial frame, add professional play/pause controls, sliders, etc. (unchanged)
1270
- (…)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1271
 
1272
  else:
1273
  # STATIC VERSION (Final state overview)
@@ -1295,8 +1392,26 @@ def create_genesis_animation(prediction_data, enable_animation=True):
1295
  )
1296
  )
1297
 
1298
- # Add complete storm tracks (unchanged)
1299
- (…)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1300
 
1301
  # FINAL LAYOUT (Professional meteorological style)
1302
  fig.update_layout(
@@ -1336,7 +1451,7 @@ def create_genesis_animation(prediction_data, enable_animation=True):
1336
  )
1337
 
1338
  return fig
1339
-
1340
  except Exception as e:
1341
  logging.error(f"Error creating professional genesis animation: {e}")
1342
  import traceback
 
1236
  intensities = [pt['intensity'] for pt in current_track]
1237
  categories = [pt['category'] for pt in current_track]
1238
 
1239
+ # Get colors based on intensity (Saffir-Simpson-like scale)
1240
+ colors = []
1241
+ for intensity in intensities:
1242
+ if intensity < 34:
1243
+ colors.append('#80808080') # Gray - TD
1244
+ elif intensity < 64:
1245
+ colors.append('#0000FF80') # Blue - TS
1246
+ elif intensity < 83:
1247
+ colors.append('#00FF0080') # Green - Cat 1
1248
+ elif intensity < 96:
1249
+ colors.append('#FFFF0080') # Yellow - Cat 2
1250
+ elif intensity < 113:
1251
+ colors.append('#FFA50080') # Orange - Cat 3
1252
+ elif intensity < 137:
1253
+ colors.append('#FF000080') # Red - Cat 4
1254
+ else:
1255
+ colors.append('#8B000080') # DarkRed - Cat 5
1256
 
1257
+ # Historical track line
1258
+ frame_data.append(
1259
+ go.Scattergeo(
1260
+ lat=lats,
1261
+ lon=lons,
1262
+ mode='lines',
1263
+ line=dict(
1264
+ width=2,
1265
+ color='gray'
1266
+ ),
1267
+ name=f"{storm_id} Track",
1268
+ showlegend=(day_idx == 0),
1269
+ hoverinfo='skip'
1270
+ )
1271
+ )
1272
+
1273
+ # Current position marker
1274
+ frame_data.append(
1275
+ go.Scattergeo(
1276
+ lat=[lats[-1]],
1277
+ lon=[lons[-1]],
1278
+ mode='markers',
1279
+ marker=dict(
1280
+ size=10,
1281
+ symbol='circle',
1282
+ color=colors[-1]
1283
+ ),
1284
+ name=f"{storm_id} Position",
1285
+ showlegend=(day_idx == 0),
1286
+ hovertemplate=(
1287
+ f"{storm_id}<br>"
1288
+ f"Lat: {lats[-1]:.1f}°N<br>"
1289
+ f"Lon: {lons[-1]:.1f}°E<br>"
1290
+ f"Intensity: {intensities[-1]} kt<br>"
1291
+ f"Category: {categories[-1]}<br>"
1292
+ '<extra></extra>'
1293
+ )
1294
+ )
1295
+ )
1296
+
1297
  # Create frame
1298
  frames.append(go.Frame(
1299
  data=frame_data,
 
1321
 
1322
  fig.frames = frames
1323
 
1324
+ # Set up initial frame, add play/pause controls, sliders, etc.
1325
+ slider_steps = [
1326
+ dict(method="animate",
1327
+ args=[[frame.name], {
1328
+ "mode": "immediate",
1329
+ "frame": {"duration": 500, "redraw": True},
1330
+ "transition": {"duration": 0}
1331
+ }],
1332
+ label=frame.name)
1333
+ for frame in frames
1334
+ ]
1335
+
1336
+ fig.update_layout(
1337
+ updatemenus=[dict(
1338
+ type="buttons",
1339
+ showactive=False,
1340
+ y=0,
1341
+ x=1.05,
1342
+ xanchor="right",
1343
+ yanchor="top",
1344
+ pad=dict(t=0, r=10),
1345
+ buttons=[
1346
+ dict(label="▶️ Play",
1347
+ method="animate",
1348
+ args=[None, {
1349
+ "frame": {"duration": 500, "redraw": True},
1350
+ "fromcurrent": True,
1351
+ "transition": {"duration": 0}
1352
+ }]),
1353
+ dict(label="⏸️ Pause",
1354
+ method="animate",
1355
+ args=[[None], {
1356
+ "frame": {"duration": 0, "redraw": False},
1357
+ "mode": "immediate",
1358
+ "transition": {"duration": 0}
1359
+ }])
1360
+ ]
1361
+ )],
1362
+ sliders=[dict(
1363
+ active=0,
1364
+ pad=dict(t=50),
1365
+ steps=slider_steps
1366
+ )]
1367
+ )
1368
 
1369
  else:
1370
  # STATIC VERSION (Final state overview)
 
1392
  )
1393
  )
1394
 
1395
+ # Add complete storm tracks
1396
+ for storm in storm_predictions:
1397
+ track = storm['track']
1398
+ if track:
1399
+ lats = [pt['lat'] for pt in track]
1400
+ lons = [pt['lon'] for pt in track]
1401
+ fig.add_trace(
1402
+ go.Scattergeo(
1403
+ lat=lats,
1404
+ lon=lons,
1405
+ mode='lines+markers',
1406
+ line=dict(width=2, color='gray'),
1407
+ marker=dict(
1408
+ size=6,
1409
+ symbol='circle',
1410
+ color='red'
1411
+ ),
1412
+ name=f"{storm['storm_id']} Full Track"
1413
+ )
1414
+ )
1415
 
1416
  # FINAL LAYOUT (Professional meteorological style)
1417
  fig.update_layout(
 
1451
  )
1452
 
1453
  return fig
1454
+
1455
  except Exception as e:
1456
  logging.error(f"Error creating professional genesis animation: {e}")
1457
  import traceback