euler314 commited on
Commit
8524a20
·
verified ·
1 Parent(s): e298a03

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +118 -37
app.py CHANGED
@@ -631,6 +631,7 @@ def get_available_years():
631
  years = sorted(years)
632
  return years
633
 
 
634
  # Function to get available typhoons for a selected year
635
  def get_typhoons_for_year(year):
636
  if not year or ibtracs is None:
@@ -638,20 +639,77 @@ def get_typhoons_for_year(year):
638
 
639
  try:
640
  year = int(year)
 
 
 
641
  season = ibtracs.get_season(year)
642
  storm_summary = season.summary()
643
 
644
  typhoon_options = []
645
  for i in range(storm_summary['season_storms']):
646
- storm_id = storm_summary['id'][i]
647
- storm_name = storm_summary['name'][i]
648
- typhoon_options.append((f"{storm_name} ({storm_id})", storm_id))
 
 
 
 
 
 
649
 
650
  return typhoon_options
651
  except Exception as e:
652
  print(f"Error getting typhoons for year {year}: {e}")
653
  return []
654
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
655
  # Create animation for typhoon path
656
  def create_typhoon_path_animation(year, typhoon_id, standard):
657
  if not year or not typhoon_id:
@@ -802,6 +860,7 @@ def create_typhoon_path_animation(year, typhoon_id, standard):
802
  print(f"Error creating typhoon path animation: {e}")
803
  return None
804
 
 
805
  # Function to analyze typhoon tracks
806
  def analyze_typhoon_tracks(start_year, start_month, end_year, end_month, enso_selection, typhoon_search=""):
807
  start_date = datetime(int(start_year), int(start_month), 1)
@@ -820,48 +879,68 @@ def analyze_typhoon_tracks(start_year, start_month, end_year, end_month, enso_se
820
  enso_value = enso_map[enso_selection]
821
 
822
  try:
 
823
  for year in range(int(start_year), int(end_year) + 1):
824
  if year not in ibtracs.data.keys():
825
  continue
826
 
827
  season = ibtracs.get_season(year)
828
  for storm_id in season.summary()['id']:
829
- storm = get_storm_data(storm_id)
830
- storm_dates = storm.time
831
-
832
- if any(start_date <= date <= end_date for date in storm_dates):
833
- storm_date_str = storm_dates[0].strftime('%Y-%b')
834
- if storm_date_str in oni_df.index:
835
- storm_oni = oni_df.loc[storm_date_str]['ONI']
836
- if isinstance(storm_oni, pd.Series):
837
- storm_oni = storm_oni.iloc[0]
838
 
839
- phase = classify_enso_phases(storm_oni)
 
 
 
 
 
 
 
 
 
 
 
 
840
 
841
- if (enso_value == 'all' or
842
- (enso_value == 'el_nino' and phase == 'El Nino') or
843
- (enso_value == 'la_nina' and phase == 'La Nina') or
844
- (enso_value == 'neutral' and phase == 'Neutral')):
845
-
846
- color = {'El Nino': 'red', 'La Nina': 'blue', 'Neutral': 'green'}[phase]
847
-
848
- # Highlight searched typhoon
849
- if typhoon_search and typhoon_search.lower() in storm.name.lower():
850
- line_width = 5
851
- line_color = 'yellow'
852
- else:
853
- line_width = 2
854
- line_color = color
855
 
856
- fig_tracks.add_trace(go.Scattergeo(
857
- lon=storm.lon,
858
- lat=storm.lat,
859
- mode='lines',
860
- name=storm.name,
861
- text=f'{storm.name} ({year})',
862
- hoverinfo='text',
863
- line=dict(width=line_width, color=line_color)
864
- ))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
865
 
866
  fig_tracks.update_layout(
867
  title=f'Typhoon Tracks from {start_year}-{start_month} to {end_year}-{end_month}',
@@ -870,6 +949,8 @@ def analyze_typhoon_tracks(start_year, start_month, end_year, end_month, enso_se
870
  showland=True,
871
  coastlinecolor='rgb(100, 100, 100)',
872
  countrycolor='rgb(204, 204, 204)',
 
 
873
  )
874
  )
875
 
@@ -884,7 +965,7 @@ def analyze_typhoon_tracks(start_year, start_month, end_year, end_month, enso_se
884
  max_wind = filtered_data['USA_WIND'].max() if not filtered_data.empty else 0
885
  min_press = filtered_data['USA_PRES'].min() if not filtered_data.empty else 0
886
 
887
- stats_text = f"Maximum Wind Speed: {max_wind:.2f} knots\nMinimum Pressure: {min_press:.2f} hPa"
888
 
889
  # Create wind scatter plot
890
  wind_oni_scatter = px.scatter(filtered_data, x='ONI', y='USA_WIND', color='Category',
 
631
  years = sorted(years)
632
  return years
633
 
634
+ # Function to get available typhoons for a selected year
635
  # Function to get available typhoons for a selected year
636
  def get_typhoons_for_year(year):
637
  if not year or ibtracs is None:
 
639
 
640
  try:
641
  year = int(year)
642
+ if year not in ibtracs.data:
643
+ return []
644
+
645
  season = ibtracs.get_season(year)
646
  storm_summary = season.summary()
647
 
648
  typhoon_options = []
649
  for i in range(storm_summary['season_storms']):
650
+ try:
651
+ storm_id = storm_summary['id'][i]
652
+ storm_name = storm_summary['name'][i]
653
+ # Use storm name as the display name, but return the ID as the value
654
+ display_name = f"{storm_name} ({storm_id})"
655
+ typhoon_options.append((display_name, storm_id))
656
+ except Exception as e:
657
+ print(f"Error retrieving typhoon info: {e}")
658
+ continue
659
 
660
  return typhoon_options
661
  except Exception as e:
662
  print(f"Error getting typhoons for year {year}: {e}")
663
  return []
664
 
665
+ # In the Gradio interface for the Typhoon Path Animation tab:
666
+ with gr.Tab("Typhoon Path Animation"):
667
+ with gr.Row():
668
+ available_years = [year for year in range(1950, 2025) if year in ibtracs.data.keys()] if ibtracs else []
669
+ year_dropdown = gr.Dropdown(
670
+ choices=available_years,
671
+ value=available_years[-1] if available_years else None,
672
+ label="Year"
673
+ )
674
+
675
+ typhoon_dropdown = gr.Dropdown(
676
+ label="Typhoon",
677
+ interactive=True
678
+ )
679
+
680
+ standard_dropdown = gr.Dropdown(
681
+ choices=["atlantic", "taiwan"],
682
+ value="atlantic",
683
+ label="Classification Standard"
684
+ )
685
+
686
+ # Update typhoon dropdown when year changes
687
+ def update_typhoon_dropdown(year):
688
+ if not year:
689
+ return [], None
690
+
691
+ typhoons = get_typhoons_for_year(year)
692
+ if not typhoons:
693
+ return [], None
694
+
695
+ return [{"label": name, "value": id} for name, id in typhoons], typhoons[0][1]
696
+
697
+ year_dropdown.change(
698
+ update_typhoon_dropdown,
699
+ inputs=year_dropdown,
700
+ outputs=[typhoon_dropdown, typhoon_dropdown]
701
+ )
702
+
703
+ animation_button = gr.Button("Generate Animation")
704
+
705
+ typhoon_animation = gr.Plot(label="Typhoon Path Animation")
706
+
707
+ animation_button.click(
708
+ create_typhoon_path_animation,
709
+ inputs=[year_dropdown, typhoon_dropdown, standard_dropdown],
710
+ outputs=typhoon_animation
711
+ )
712
+
713
  # Create animation for typhoon path
714
  def create_typhoon_path_animation(year, typhoon_id, standard):
715
  if not year or not typhoon_id:
 
860
  print(f"Error creating typhoon path animation: {e}")
861
  return None
862
 
863
+ # Function to analyze typhoon tracks
864
  # Function to analyze typhoon tracks
865
  def analyze_typhoon_tracks(start_year, start_month, end_year, end_month, enso_selection, typhoon_search=""):
866
  start_date = datetime(int(start_year), int(start_month), 1)
 
879
  enso_value = enso_map[enso_selection]
880
 
881
  try:
882
+ processed_storms = 0
883
  for year in range(int(start_year), int(end_year) + 1):
884
  if year not in ibtracs.data.keys():
885
  continue
886
 
887
  season = ibtracs.get_season(year)
888
  for storm_id in season.summary()['id']:
889
+ try:
890
+ storm = get_storm_data(storm_id)
891
+ storm_dates = storm.time
892
+
893
+ if any(start_date <= date <= end_date for date in storm_dates):
894
+ storm_date_str = storm_dates[0].strftime('%Y-%b')
895
+ storm_oni = None
 
 
896
 
897
+ # Find the ONI value - handle case where date might not be in index
898
+ if storm_date_str in oni_df.index:
899
+ storm_oni = oni_df.loc[storm_date_str]['ONI']
900
+ if isinstance(storm_oni, pd.Series):
901
+ storm_oni = storm_oni.iloc[0]
902
+ else:
903
+ # Try to find closest date
904
+ closest_dates = oni_df.index[oni_df.index.year == storm_dates[0].year]
905
+ if len(closest_dates) > 0:
906
+ closest_date = min(closest_dates, key=lambda x: abs((x - storm_dates[0].to_pydatetime()).total_seconds()))
907
+ storm_oni = oni_df.loc[closest_date]['ONI']
908
+ if isinstance(storm_oni, pd.Series):
909
+ storm_oni = storm_oni.iloc[0]
910
 
911
+ if storm_oni is not None:
912
+ phase = classify_enso_phases(storm_oni)
 
 
 
 
 
 
 
 
 
 
 
 
913
 
914
+ if (enso_value == 'all' or
915
+ (enso_value == 'el_nino' and phase == 'El Nino') or
916
+ (enso_value == 'la_nina' and phase == 'La Nina') or
917
+ (enso_value == 'neutral' and phase == 'Neutral')):
918
+
919
+ color = {'El Nino': 'red', 'La Nina': 'blue', 'Neutral': 'green'}[phase]
920
+
921
+ # Highlight searched typhoon
922
+ if typhoon_search and typhoon_search.lower() in storm.name.lower():
923
+ line_width = 5
924
+ line_color = 'yellow'
925
+ else:
926
+ line_width = 2
927
+ line_color = color
928
+
929
+ fig_tracks.add_trace(go.Scattergeo(
930
+ lon=storm.lon,
931
+ lat=storm.lat,
932
+ mode='lines',
933
+ name=storm.name,
934
+ text=f'{storm.name} ({year})',
935
+ hoverinfo='text',
936
+ line=dict(width=line_width, color=line_color)
937
+ ))
938
+ processed_storms += 1
939
+ except Exception as e:
940
+ print(f"Error processing storm {storm_id}: {e}")
941
+ continue
942
+
943
+ print(f"Processed {processed_storms} storms for track display.")
944
 
945
  fig_tracks.update_layout(
946
  title=f'Typhoon Tracks from {start_year}-{start_month} to {end_year}-{end_month}',
 
949
  showland=True,
950
  coastlinecolor='rgb(100, 100, 100)',
951
  countrycolor='rgb(204, 204, 204)',
952
+ showocean=True,
953
+ oceancolor='rgb(230, 250, 255)',
954
  )
955
  )
956
 
 
965
  max_wind = filtered_data['USA_WIND'].max() if not filtered_data.empty else 0
966
  min_press = filtered_data['USA_PRES'].min() if not filtered_data.empty else 0
967
 
968
+ stats_text = f"Maximum Wind Speed: {max_wind:.2f} knots\nMinimum Pressure: {min_press:.2f} hPa\nTotal Storms: {processed_storms}"
969
 
970
  # Create wind scatter plot
971
  wind_oni_scatter = px.scatter(filtered_data, x='ONI', y='USA_WIND', color='Category',