Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -380,7 +380,22 @@ def perform_longitude_regression(start_year, start_month, end_year, end_month):
|
|
380 |
with gr.Blocks(title="Typhoon Analysis Dashboard") as demo:
|
381 |
gr.Markdown("# Typhoon Analysis Dashboard")
|
382 |
|
383 |
-
with gr.Tab("
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
384 |
with gr.Row():
|
385 |
start_year = gr.Number(label="Start Year", value=2000, minimum=1900, maximum=2024, step=1)
|
386 |
start_month = gr.Dropdown(label="Start Month", choices=list(range(1, 13)), value=1)
|
@@ -388,25 +403,177 @@ with gr.Blocks(title="Typhoon Analysis Dashboard") as demo:
|
|
388 |
end_month = gr.Dropdown(label="End Month", choices=list(range(1, 13)), value=6)
|
389 |
enso_phase = gr.Dropdown(label="ENSO Phase", choices=['all', 'El Nino', 'La Nina', 'Neutral'], value='all')
|
390 |
typhoon_search = gr.Textbox(label="Typhoon Search")
|
391 |
-
analyze_btn = gr.Button("
|
392 |
-
|
393 |
-
tracks_plot = gr.Plot(label="Typhoon Tracks")
|
394 |
-
wind_scatter = gr.Plot(label="Wind Speed vs ONI")
|
395 |
-
pressure_scatter = gr.Plot(label="Pressure vs ONI")
|
396 |
-
regression_plot = gr.Plot(label="Regression Analysis")
|
397 |
-
slopes_text = gr.Textbox(label="Regression Slopes")
|
398 |
analyze_btn.click(
|
399 |
-
fn=generate_main_analysis,
|
400 |
inputs=[start_year, start_month, end_year, end_month, enso_phase, typhoon_search],
|
401 |
-
outputs=
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
402 |
)
|
403 |
|
404 |
with gr.Tab("Typhoon Path Animation"):
|
405 |
-
|
406 |
-
|
407 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
408 |
path_plot = gr.Plot(label="Typhoon Path Animation")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
409 |
|
|
|
410 |
def update_typhoon_options(year):
|
411 |
season = ibtracs.get_season(int(year))
|
412 |
storm_summary = season.summary()
|
@@ -414,20 +581,10 @@ with gr.Blocks(title="Typhoon Analysis Dashboard") as demo:
|
|
414 |
return gr.update(choices=options, value=options[0] if options else None)
|
415 |
|
416 |
year_dropdown.change(fn=update_typhoon_options, inputs=year_dropdown, outputs=typhoon_dropdown)
|
417 |
-
|
418 |
-
fn=
|
419 |
inputs=[year_dropdown, typhoon_dropdown, standard_dropdown],
|
420 |
outputs=path_plot
|
421 |
)
|
422 |
-
|
423 |
-
with gr.Tab("Logistic Regressions"):
|
424 |
-
with gr.Row():
|
425 |
-
wind_btn = gr.Button("Wind Speed Regression")
|
426 |
-
pressure_btn = gr.Button("Pressure Regression")
|
427 |
-
longitude_btn = gr.Button("Longitude Regression")
|
428 |
-
regression_results = gr.Textbox(label="Regression Results", lines=10)
|
429 |
-
wind_btn.click(fn=perform_wind_regression, inputs=[start_year, start_month, end_year, end_month], outputs=regression_results)
|
430 |
-
pressure_btn.click(fn=perform_pressure_regression, inputs=[start_year, start_month, end_year, end_month], outputs=regression_results)
|
431 |
-
longitude_btn.click(fn=perform_longitude_regression, inputs=[start_year, start_month, end_year, end_month], outputs=regression_results)
|
432 |
|
433 |
demo.launch()
|
|
|
380 |
with gr.Blocks(title="Typhoon Analysis Dashboard") as demo:
|
381 |
gr.Markdown("# Typhoon Analysis Dashboard")
|
382 |
|
383 |
+
with gr.Tab("Overview"):
|
384 |
+
gr.Markdown("""
|
385 |
+
## Welcome to the Typhoon Analysis Dashboard
|
386 |
+
|
387 |
+
This dashboard allows you to analyze typhoon data in relation to ENSO phases.
|
388 |
+
|
389 |
+
### Features:
|
390 |
+
- **Track Visualization**: View typhoon tracks by time period and ENSO phase
|
391 |
+
- **Statistical Analysis**: Examine relationships between ONI values and typhoon characteristics
|
392 |
+
- **Path Animation**: Watch animated typhoon paths with intensity classification
|
393 |
+
- **Regression Analysis**: Perform statistical regression on typhoon data
|
394 |
+
|
395 |
+
Select a tab above to begin your analysis.
|
396 |
+
""")
|
397 |
+
|
398 |
+
with gr.Tab("Track Visualization"):
|
399 |
with gr.Row():
|
400 |
start_year = gr.Number(label="Start Year", value=2000, minimum=1900, maximum=2024, step=1)
|
401 |
start_month = gr.Dropdown(label="Start Month", choices=list(range(1, 13)), value=1)
|
|
|
403 |
end_month = gr.Dropdown(label="End Month", choices=list(range(1, 13)), value=6)
|
404 |
enso_phase = gr.Dropdown(label="ENSO Phase", choices=['all', 'El Nino', 'La Nina', 'Neutral'], value='all')
|
405 |
typhoon_search = gr.Textbox(label="Typhoon Search")
|
406 |
+
analyze_btn = gr.Button("Generate Tracks")
|
407 |
+
tracks_plot = gr.Plot(label="Typhoon Tracks")
|
|
|
|
|
|
|
|
|
|
|
408 |
analyze_btn.click(
|
409 |
+
fn=lambda *args: generate_main_analysis(*args)[0], # Only return the tracks plot
|
410 |
inputs=[start_year, start_month, end_year, end_month, enso_phase, typhoon_search],
|
411 |
+
outputs=tracks_plot
|
412 |
+
)
|
413 |
+
|
414 |
+
with gr.Tab("Wind Analysis"):
|
415 |
+
with gr.Row():
|
416 |
+
wind_start_year = gr.Number(label="Start Year", value=2000, minimum=1900, maximum=2024, step=1)
|
417 |
+
wind_start_month = gr.Dropdown(label="Start Month", choices=list(range(1, 13)), value=1)
|
418 |
+
wind_end_year = gr.Number(label="End Year", value=2024, minimum=1900, maximum=2024, step=1)
|
419 |
+
wind_end_month = gr.Dropdown(label="End Month", choices=list(range(1, 13)), value=6)
|
420 |
+
wind_enso_phase = gr.Dropdown(label="ENSO Phase", choices=['all', 'El Nino', 'La Nina', 'Neutral'], value='all')
|
421 |
+
wind_typhoon_search = gr.Textbox(label="Typhoon Search")
|
422 |
+
wind_analyze_btn = gr.Button("Generate Wind Analysis")
|
423 |
+
wind_scatter = gr.Plot(label="Wind Speed vs ONI")
|
424 |
+
wind_regression_results = gr.Textbox(label="Wind Regression Results")
|
425 |
+
wind_analyze_btn.click(
|
426 |
+
fn=lambda *args: [generate_main_analysis(*args)[1], perform_wind_regression(args[0], args[1], args[2], args[3])],
|
427 |
+
inputs=[wind_start_year, wind_start_month, wind_end_year, wind_end_month, wind_enso_phase, wind_typhoon_search],
|
428 |
+
outputs=[wind_scatter, wind_regression_results]
|
429 |
+
)
|
430 |
+
|
431 |
+
with gr.Tab("Pressure Analysis"):
|
432 |
+
with gr.Row():
|
433 |
+
pressure_start_year = gr.Number(label="Start Year", value=2000, minimum=1900, maximum=2024, step=1)
|
434 |
+
pressure_start_month = gr.Dropdown(label="Start Month", choices=list(range(1, 13)), value=1)
|
435 |
+
pressure_end_year = gr.Number(label="End Year", value=2024, minimum=1900, maximum=2024, step=1)
|
436 |
+
pressure_end_month = gr.Dropdown(label="End Month", choices=list(range(1, 13)), value=6)
|
437 |
+
pressure_enso_phase = gr.Dropdown(label="ENSO Phase", choices=['all', 'El Nino', 'La Nina', 'Neutral'], value='all')
|
438 |
+
pressure_typhoon_search = gr.Textbox(label="Typhoon Search")
|
439 |
+
pressure_analyze_btn = gr.Button("Generate Pressure Analysis")
|
440 |
+
pressure_scatter = gr.Plot(label="Pressure vs ONI")
|
441 |
+
pressure_regression_results = gr.Textbox(label="Pressure Regression Results")
|
442 |
+
pressure_analyze_btn.click(
|
443 |
+
fn=lambda *args: [generate_main_analysis(*args)[2], perform_pressure_regression(args[0], args[1], args[2], args[3])],
|
444 |
+
inputs=[pressure_start_year, pressure_start_month, pressure_end_year, pressure_end_month, pressure_enso_phase, pressure_typhoon_search],
|
445 |
+
outputs=[pressure_scatter, pressure_regression_results]
|
446 |
+
)
|
447 |
+
|
448 |
+
with gr.Tab("Longitude Analysis"):
|
449 |
+
with gr.Row():
|
450 |
+
lon_start_year = gr.Number(label="Start Year", value=2000, minimum=1900, maximum=2024, step=1)
|
451 |
+
lon_start_month = gr.Dropdown(label="Start Month", choices=list(range(1, 13)), value=1)
|
452 |
+
lon_end_year = gr.Number(label="End Year", value=2024, minimum=1900, maximum=2024, step=1)
|
453 |
+
lon_end_month = gr.Dropdown(label="End Month", choices=list(range(1, 13)), value=6)
|
454 |
+
lon_enso_phase = gr.Dropdown(label="ENSO Phase", choices=['all', 'El Nino', 'La Nina', 'Neutral'], value='all')
|
455 |
+
lon_analyze_btn = gr.Button("Generate Longitude Analysis")
|
456 |
+
regression_plot = gr.Plot(label="Longitude vs ONI")
|
457 |
+
slopes_text = gr.Textbox(label="Regression Slopes")
|
458 |
+
lon_regression_results = gr.Textbox(label="Longitude Regression Results")
|
459 |
+
lon_analyze_btn.click(
|
460 |
+
fn=lambda *args: [generate_main_analysis(*args)[3], generate_main_analysis(*args)[4],
|
461 |
+
perform_longitude_regression(args[0], args[1], args[2], args[3])],
|
462 |
+
inputs=[lon_start_year, lon_start_month, lon_end_year, lon_end_month, lon_enso_phase, ""],
|
463 |
+
outputs=[regression_plot, slopes_text, lon_regression_results]
|
464 |
)
|
465 |
|
466 |
with gr.Tab("Typhoon Path Animation"):
|
467 |
+
with gr.Row():
|
468 |
+
year_dropdown = gr.Dropdown(label="Year", choices=[str(y) for y in range(1950, 2025)], value="2024")
|
469 |
+
typhoon_dropdown = gr.Dropdown(label="Typhoon")
|
470 |
+
standard_dropdown = gr.Dropdown(label="Classification Standard",
|
471 |
+
choices=['atlantic', 'taiwan'], value='atlantic')
|
472 |
+
|
473 |
+
# Fix the animation with modified function
|
474 |
+
def generate_fixed_path_animation(year, typhoon, standard):
|
475 |
+
typhoon_id = typhoon.split('(')[-1].strip(')')
|
476 |
+
storm = ibtracs.get_storm(typhoon_id)
|
477 |
+
|
478 |
+
# Create better frames for animation
|
479 |
+
frames = []
|
480 |
+
for i in range(len(storm.time)):
|
481 |
+
category, color = categorize_typhoon_by_standard(storm.vmax[i], standard)
|
482 |
+
frames.append(
|
483 |
+
go.Frame(
|
484 |
+
data=[
|
485 |
+
go.Scattergeo(
|
486 |
+
lon=storm.lon[:i+1], lat=storm.lat[:i+1],
|
487 |
+
mode='lines', line=dict(width=2, color='blue'),
|
488 |
+
name="Path"
|
489 |
+
),
|
490 |
+
go.Scattergeo(
|
491 |
+
lon=[storm.lon[i]], lat=[storm.lat[i]],
|
492 |
+
mode='markers',
|
493 |
+
marker=dict(size=10, color=color),
|
494 |
+
name=f"Position at {storm.time[i].strftime('%Y-%m-%d %H:%M')}",
|
495 |
+
text=f"Wind: {storm.vmax[i]} kt<br>Category: {category}"
|
496 |
+
)
|
497 |
+
],
|
498 |
+
name=f"frame{i}"
|
499 |
+
)
|
500 |
+
)
|
501 |
+
|
502 |
+
# Initial plot
|
503 |
+
fig = go.Figure(
|
504 |
+
data=[
|
505 |
+
go.Scattergeo(
|
506 |
+
lon=[storm.lon[0]], lat=[storm.lat[0]],
|
507 |
+
mode='markers', marker=dict(size=10, color='green'),
|
508 |
+
name="Start Position"
|
509 |
+
)
|
510 |
+
],
|
511 |
+
frames=frames
|
512 |
+
)
|
513 |
+
|
514 |
+
# Update layout with better animation controls
|
515 |
+
fig.update_layout(
|
516 |
+
title=f"{year} {storm.name} Typhoon Path",
|
517 |
+
geo=dict(
|
518 |
+
projection_type='natural earth',
|
519 |
+
showland=True,
|
520 |
+
showcoastlines=True,
|
521 |
+
landcolor='rgb(243, 243, 243)',
|
522 |
+
countrycolor='rgb(204, 204, 204)',
|
523 |
+
coastlinecolor='rgb(204, 204, 204)',
|
524 |
+
lataxis={'range': [min(storm.lat)-5, max(storm.lat)+5]},
|
525 |
+
lonaxis={'range': [min(storm.lon)-10, max(storm.lon)+10]}
|
526 |
+
),
|
527 |
+
updatemenus=[{
|
528 |
+
"buttons": [
|
529 |
+
{
|
530 |
+
"args": [None, {"frame": {"duration": 200, "redraw": True}, "fromcurrent": True}],
|
531 |
+
"label": "Play",
|
532 |
+
"method": "animate"
|
533 |
+
},
|
534 |
+
{
|
535 |
+
"args": [[None], {"frame": {"duration": 0, "redraw": True}, "mode": "immediate"}],
|
536 |
+
"label": "Pause",
|
537 |
+
"method": "animate"
|
538 |
+
}
|
539 |
+
],
|
540 |
+
"direction": "left",
|
541 |
+
"pad": {"r": 10, "t": 10},
|
542 |
+
"type": "buttons",
|
543 |
+
"x": 0.1,
|
544 |
+
"y": 0
|
545 |
+
}],
|
546 |
+
sliders=[{
|
547 |
+
"active": 0,
|
548 |
+
"steps": [
|
549 |
+
{
|
550 |
+
"args": [[f.name], {
|
551 |
+
"frame": {"duration": 0, "redraw": True},
|
552 |
+
"mode": "immediate"
|
553 |
+
}],
|
554 |
+
"label": str(i),
|
555 |
+
"method": "animate"
|
556 |
+
} for i, f in enumerate(frames)
|
557 |
+
],
|
558 |
+
"x": 0.1,
|
559 |
+
"y": 0,
|
560 |
+
"len": 0.9
|
561 |
+
}]
|
562 |
+
)
|
563 |
+
|
564 |
+
return fig
|
565 |
+
|
566 |
+
animate_btn = gr.Button("Generate Animation")
|
567 |
path_plot = gr.Plot(label="Typhoon Path Animation")
|
568 |
+
animation_info = gr.Markdown("""
|
569 |
+
### Animation Instructions
|
570 |
+
1. Select a year and typhoon from the dropdowns
|
571 |
+
2. Click "Generate Animation"
|
572 |
+
3. Use the play button to start the animation
|
573 |
+
4. Use the slider to scrub through different positions
|
574 |
+
""")
|
575 |
|
576 |
+
# Year dropdown change function
|
577 |
def update_typhoon_options(year):
|
578 |
season = ibtracs.get_season(int(year))
|
579 |
storm_summary = season.summary()
|
|
|
581 |
return gr.update(choices=options, value=options[0] if options else None)
|
582 |
|
583 |
year_dropdown.change(fn=update_typhoon_options, inputs=year_dropdown, outputs=typhoon_dropdown)
|
584 |
+
animate_btn.click(
|
585 |
+
fn=generate_fixed_path_animation,
|
586 |
inputs=[year_dropdown, typhoon_dropdown, standard_dropdown],
|
587 |
outputs=path_plot
|
588 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
589 |
|
590 |
demo.launch()
|