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()
|