Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -1,4 +1,3 @@
|
|
1 |
-
# -*- coding: utf-8 -*-
|
2 |
import os
|
3 |
import argparse
|
4 |
import logging
|
@@ -116,7 +115,7 @@ CACHE_EXPIRY_DAYS = 1
|
|
116 |
# Enhanced color mapping with TD support (for Plotly)
|
117 |
enhanced_color_map = {
|
118 |
'Unknown': 'rgb(200, 200, 200)',
|
119 |
-
'Tropical Depression': 'rgb(128, 128, 128)', #
|
120 |
'Tropical Storm': 'rgb(0, 0, 255)',
|
121 |
'C1 Typhoon': 'rgb(0, 255, 255)',
|
122 |
'C2 Typhoon': 'rgb(0, 255, 0)',
|
@@ -1028,20 +1027,20 @@ def create_advanced_clustering_visualization(storm_features, typhoon_data, metho
|
|
1028 |
storm_count = int(cluster_row['SID_count'])
|
1029 |
|
1030 |
stats_text += f"CLUSTER {cluster}: {storm_count} storms\n"
|
1031 |
-
stats_text += f" Intensity: {cluster_row['USA_WIND_max_mean']:.1f}
|
1032 |
-
stats_text += f" Pressure: {cluster_row['USA_PRES_min_mean']:.1f}
|
1033 |
-
stats_text += f" Track Length: {cluster_row['track_length_mean']:.1f}
|
1034 |
stats_text += f" Genesis Region: {cluster_row['genesis_lat']:.1f}°N, {cluster_row['genesis_lon']:.1f}°E\n"
|
1035 |
stats_text += f" Avg Distance: {cluster_row['total_distance_mean']:.2f} degrees\n"
|
1036 |
stats_text += f" Avg Curvature: {cluster_row['avg_curvature_mean']:.3f} radians\n\n"
|
1037 |
|
1038 |
# Add feature importance summary
|
1039 |
stats_text += "CLUSTERING FEATURES USED:\n"
|
1040 |
-
stats_text +=
|
1041 |
-
stats_text +=
|
1042 |
-
stats_text +=
|
1043 |
-
stats_text +=
|
1044 |
-
stats_text += f"
|
1045 |
|
1046 |
stats_text += f"ALGORITHM: {method.upper()} + DBSCAN clustering\n"
|
1047 |
stats_text += f"CLUSTERS FOUND: {len([c for c in storm_features_viz['cluster'].unique() if c != -1])}\n"
|
@@ -1726,30 +1725,31 @@ def create_interface():
|
|
1726 |
gr.Markdown("Advanced ML clustering, CNN predictions, and comprehensive tropical cyclone analysis including Tropical Depressions")
|
1727 |
|
1728 |
with gr.Tab("Overview"):
|
1729 |
-
|
1730 |
## Welcome to the Enhanced Typhoon Analysis Dashboard
|
1731 |
|
1732 |
This dashboard provides comprehensive analysis of typhoon data in relation to ENSO phases with advanced machine learning capabilities.
|
1733 |
|
1734 |
### Enhanced Features:
|
1735 |
-
-
|
1736 |
-
-
|
1737 |
-
-
|
1738 |
-
-
|
1739 |
-
-
|
1740 |
|
1741 |
### Data Status:
|
1742 |
-
-
|
1743 |
-
-
|
1744 |
-
-
|
1745 |
-
-
|
1746 |
|
1747 |
### Technical Capabilities:
|
1748 |
-
-
|
1749 |
-
-
|
1750 |
-
-
|
1751 |
-
-
|
1752 |
-
"""
|
|
|
1753 |
|
1754 |
with gr.Tab("Advanced ML Clustering with Routes"):
|
1755 |
gr.Markdown("## Storm Pattern Analysis using UMAP/t-SNE with Route Visualization")
|
@@ -1792,30 +1792,31 @@ def create_interface():
|
|
1792 |
outputs=[cluster_plot, cluster_stats]
|
1793 |
)
|
1794 |
|
1795 |
-
|
1796 |
### Advanced Clustering Features:
|
1797 |
-
-
|
1798 |
-
-
|
1799 |
-
-
|
1800 |
-
-
|
1801 |
-
-
|
1802 |
|
1803 |
### How to Interpret:
|
1804 |
-
-
|
1805 |
-
-
|
1806 |
-
-
|
1807 |
-
-
|
1808 |
-
"""
|
|
|
1809 |
|
1810 |
-
with gr.Tab("
|
1811 |
gr.Markdown("## AI-Powered Storm Intensity Forecasting")
|
1812 |
|
1813 |
if CNN_AVAILABLE:
|
1814 |
-
gr.Markdown("
|
1815 |
method_description = "Using Convolutional Neural Networks for advanced intensity prediction"
|
1816 |
else:
|
1817 |
-
gr.Markdown("
|
1818 |
-
gr.Markdown("*Install TensorFlow for deep learning features: pip install tensorflow-cpu
|
1819 |
method_description = "Using established meteorological relationships and climatology"
|
1820 |
|
1821 |
gr.Markdown(f"**Current Method**: {method_description}")
|
@@ -1838,22 +1839,22 @@ def create_interface():
|
|
1838 |
outputs=[intensity_output, confidence_output]
|
1839 |
)
|
1840 |
|
1841 |
-
|
1842 |
-
|
1843 |
-
|
1844 |
-
-
|
1845 |
-
-
|
1846 |
-
-
|
1847 |
-
- **Robust Fallbacks**: Works with or without deep learning libraries
|
1848 |
|
1849 |
-
###
|
1850 |
-
-
|
1851 |
-
-
|
1852 |
-
-
|
1853 |
-
-
|
1854 |
-
"""
|
1855 |
-
|
1856 |
-
|
|
|
1857 |
with gr.Row():
|
1858 |
start_year = gr.Number(label="Start Year", value=2020)
|
1859 |
start_month = gr.Dropdown(label="Start Month", choices=list(range(1, 13)), value=1)
|
@@ -1870,7 +1871,7 @@ def create_interface():
|
|
1870 |
outputs=[tracks_plot, typhoon_count]
|
1871 |
)
|
1872 |
|
1873 |
-
with gr.Tab("
|
1874 |
with gr.Row():
|
1875 |
wind_start_year = gr.Number(label="Start Year", value=2020)
|
1876 |
wind_start_month = gr.Dropdown(label="Start Month", choices=list(range(1, 13)), value=1)
|
@@ -1887,7 +1888,7 @@ def create_interface():
|
|
1887 |
outputs=[wind_scatter, wind_regression_results]
|
1888 |
)
|
1889 |
|
1890 |
-
with gr.Tab("
|
1891 |
with gr.Row():
|
1892 |
pressure_start_year = gr.Number(label="Start Year", value=2020)
|
1893 |
pressure_start_month = gr.Dropdown(label="Start Month", choices=list(range(1, 13)), value=1)
|
@@ -1904,7 +1905,7 @@ def create_interface():
|
|
1904 |
outputs=[pressure_scatter, pressure_regression_results]
|
1905 |
)
|
1906 |
|
1907 |
-
with gr.Tab("
|
1908 |
with gr.Row():
|
1909 |
lon_start_year = gr.Number(label="Start Year", value=2020)
|
1910 |
lon_start_month = gr.Dropdown(label="Start Month", choices=list(range(1, 13)), value=1)
|
@@ -1922,7 +1923,7 @@ def create_interface():
|
|
1922 |
outputs=[regression_plot, slopes_text, lon_regression_results]
|
1923 |
)
|
1924 |
|
1925 |
-
with gr.Tab("
|
1926 |
gr.Markdown("## High-Quality Storm Track Visualization (All Categories Including TD)")
|
1927 |
|
1928 |
with gr.Row():
|
@@ -1963,16 +1964,17 @@ def create_interface():
|
|
1963 |
outputs=[video_output]
|
1964 |
)
|
1965 |
|
1966 |
-
|
1967 |
### Enhanced Animation Features:
|
1968 |
-
-
|
1969 |
-
-
|
1970 |
-
-
|
1971 |
-
-
|
1972 |
-
-
|
1973 |
-
-
|
1974 |
-
-
|
1975 |
-
"""
|
|
|
1976 |
|
1977 |
with gr.Tab("Data Statistics & Insights"):
|
1978 |
gr.Markdown("## Comprehensive Dataset Analysis")
|
@@ -2036,7 +2038,7 @@ def create_interface():
|
|
2036 |
except Exception as e:
|
2037 |
gr.Markdown(f"Visualization error: {str(e)}")
|
2038 |
|
2039 |
-
# Enhanced statistics
|
2040 |
total_storms = len(typhoon_data['SID'].unique()) if 'SID' in typhoon_data.columns else 0
|
2041 |
total_records = len(typhoon_data)
|
2042 |
|
@@ -2079,26 +2081,27 @@ def create_interface():
|
|
2079 |
td_storms = ts_storms = typhoon_storms = 0
|
2080 |
td_percentage = 0
|
2081 |
|
2082 |
-
|
|
|
2083 |
### Enhanced Dataset Summary:
|
2084 |
-
-
|
2085 |
-
-
|
2086 |
-
-
|
2087 |
-
-
|
2088 |
-
-
|
2089 |
|
2090 |
### Storm Category Breakdown:
|
2091 |
-
-
|
2092 |
-
-
|
2093 |
-
-
|
2094 |
|
2095 |
### New Platform Capabilities:
|
2096 |
-
-
|
2097 |
-
-
|
2098 |
-
-
|
2099 |
-
-
|
2100 |
-
-
|
2101 |
-
-
|
2102 |
|
2103 |
### Research Applications:
|
2104 |
- Climate change impact studies
|
@@ -2106,7 +2109,8 @@ def create_interface():
|
|
2106 |
- Storm pattern classification
|
2107 |
- ENSO-typhoon relationship analysis
|
2108 |
- Intensity prediction model development
|
2109 |
-
"""
|
|
|
2110 |
|
2111 |
return demo
|
2112 |
except Exception as e:
|
@@ -2188,7 +2192,7 @@ def test_color_conversion():
|
|
2188 |
plotly_color = enhanced_color_map.get(category, 'rgb(128,128,128)')
|
2189 |
matplotlib_color = get_matplotlib_color(category)
|
2190 |
|
2191 |
-
print(f"Wind: {wind:3d}kt
|
2192 |
|
2193 |
print("Color conversion test complete!")
|
2194 |
|
@@ -2204,7 +2208,7 @@ def test_rgb_conversion():
|
|
2204 |
print("Testing RGB to hex conversion...")
|
2205 |
for rgb_str in test_colors:
|
2206 |
hex_color = rgb_string_to_hex(rgb_str)
|
2207 |
-
print(f"{rgb_str:20s}
|
2208 |
|
2209 |
print("RGB conversion test complete!")
|
2210 |
|
|
|
|
|
1 |
import os
|
2 |
import argparse
|
3 |
import logging
|
|
|
115 |
# Enhanced color mapping with TD support (for Plotly)
|
116 |
enhanced_color_map = {
|
117 |
'Unknown': 'rgb(200, 200, 200)',
|
118 |
+
'Tropical Depression': 'rgb(128, 128, 128)', # Gray for TD
|
119 |
'Tropical Storm': 'rgb(0, 0, 255)',
|
120 |
'C1 Typhoon': 'rgb(0, 255, 255)',
|
121 |
'C2 Typhoon': 'rgb(0, 255, 0)',
|
|
|
1027 |
storm_count = int(cluster_row['SID_count'])
|
1028 |
|
1029 |
stats_text += f"CLUSTER {cluster}: {storm_count} storms\n"
|
1030 |
+
stats_text += f" Intensity: {cluster_row['USA_WIND_max_mean']:.1f} +/- {cluster_row['USA_WIND_max_std']:.1f} kt\n"
|
1031 |
+
stats_text += f" Pressure: {cluster_row['USA_PRES_min_mean']:.1f} +/- {cluster_row['USA_PRES_min_std']:.1f} hPa\n"
|
1032 |
+
stats_text += f" Track Length: {cluster_row['track_length_mean']:.1f} +/- {cluster_row['track_length_std']:.1f} points\n"
|
1033 |
stats_text += f" Genesis Region: {cluster_row['genesis_lat']:.1f}°N, {cluster_row['genesis_lon']:.1f}°E\n"
|
1034 |
stats_text += f" Avg Distance: {cluster_row['total_distance_mean']:.2f} degrees\n"
|
1035 |
stats_text += f" Avg Curvature: {cluster_row['avg_curvature_mean']:.3f} radians\n\n"
|
1036 |
|
1037 |
# Add feature importance summary
|
1038 |
stats_text += "CLUSTERING FEATURES USED:\n"
|
1039 |
+
stats_text += " - Storm intensity (max/mean/std wind & pressure)\n"
|
1040 |
+
stats_text += " - Track characteristics (length, curvature, distance)\n"
|
1041 |
+
stats_text += " - Genesis location (lat/lon)\n"
|
1042 |
+
stats_text += " - Geographic range (lat/lon span)\n"
|
1043 |
+
stats_text += f" - Total features: {len(feature_cols)}\n\n"
|
1044 |
|
1045 |
stats_text += f"ALGORITHM: {method.upper()} + DBSCAN clustering\n"
|
1046 |
stats_text += f"CLUSTERS FOUND: {len([c for c in storm_features_viz['cluster'].unique() if c != -1])}\n"
|
|
|
1725 |
gr.Markdown("Advanced ML clustering, CNN predictions, and comprehensive tropical cyclone analysis including Tropical Depressions")
|
1726 |
|
1727 |
with gr.Tab("Overview"):
|
1728 |
+
overview_text = f"""
|
1729 |
## Welcome to the Enhanced Typhoon Analysis Dashboard
|
1730 |
|
1731 |
This dashboard provides comprehensive analysis of typhoon data in relation to ENSO phases with advanced machine learning capabilities.
|
1732 |
|
1733 |
### Enhanced Features:
|
1734 |
+
- Advanced ML Clustering: UMAP/t-SNE storm pattern analysis with route visualization
|
1735 |
+
- Optional CNN Predictions: Deep learning intensity forecasting
|
1736 |
+
- Complete TD Support: Now includes Tropical Depressions (< 34 kt)
|
1737 |
+
- 2025 Data Ready: Real-time compatibility with current year data
|
1738 |
+
- Enhanced Animations: High-quality storm track visualizations
|
1739 |
|
1740 |
### Data Status:
|
1741 |
+
- ONI Data: {len(oni_data)} years loaded
|
1742 |
+
- Typhoon Data: {total_records} records loaded
|
1743 |
+
- Merged Data: {len(merged_data)} typhoons with ONI values
|
1744 |
+
- Available Years: {year_range_display}
|
1745 |
|
1746 |
### Technical Capabilities:
|
1747 |
+
- UMAP Clustering: {"Available" if UMAP_AVAILABLE else "Limited to t-SNE/PCA"}
|
1748 |
+
- AI Predictions: {"Deep Learning" if CNN_AVAILABLE else "Physics-based"}
|
1749 |
+
- Enhanced Categorization: Tropical Depression to Super Typhoon
|
1750 |
+
- Platform Compatibility: Optimized for Hugging Face Spaces
|
1751 |
+
"""
|
1752 |
+
gr.Markdown(overview_text)
|
1753 |
|
1754 |
with gr.Tab("Advanced ML Clustering with Routes"):
|
1755 |
gr.Markdown("## Storm Pattern Analysis using UMAP/t-SNE with Route Visualization")
|
|
|
1792 |
outputs=[cluster_plot, cluster_stats]
|
1793 |
)
|
1794 |
|
1795 |
+
cluster_info_text = """
|
1796 |
### Advanced Clustering Features:
|
1797 |
+
- Multi-dimensional Analysis: Uses 15+ storm characteristics including intensity, track shape, genesis location
|
1798 |
+
- Route Visualization: Shows actual storm tracks colored by cluster membership
|
1799 |
+
- DBSCAN Clustering: Automatically finds natural groupings without predefined cluster count
|
1800 |
+
- Comprehensive Stats: Detailed cluster analysis including intensity, pressure, track length, curvature
|
1801 |
+
- Interactive: Hover over points to see storm details, zoom and pan the route map
|
1802 |
|
1803 |
### How to Interpret:
|
1804 |
+
- Left Plot: Each dot is a storm positioned by similarity (close = similar characteristics)
|
1805 |
+
- Right Plot: Actual geographic storm tracks, colored by which cluster they belong to
|
1806 |
+
- Cluster Colors: Each cluster gets a unique color to identify similar storm patterns
|
1807 |
+
- Noise Points: Gray points represent storms that don't fit clear patterns
|
1808 |
+
"""
|
1809 |
+
gr.Markdown(cluster_info_text)
|
1810 |
|
1811 |
+
with gr.Tab("Intensity Prediction"):
|
1812 |
gr.Markdown("## AI-Powered Storm Intensity Forecasting")
|
1813 |
|
1814 |
if CNN_AVAILABLE:
|
1815 |
+
gr.Markdown("Deep Learning models available - TensorFlow loaded successfully")
|
1816 |
method_description = "Using Convolutional Neural Networks for advanced intensity prediction"
|
1817 |
else:
|
1818 |
+
gr.Markdown("Physics-based models available - Using climatological relationships")
|
1819 |
+
gr.Markdown("*Install TensorFlow for deep learning features: `pip install tensorflow-cpu`*")
|
1820 |
method_description = "Using established meteorological relationships and climatology"
|
1821 |
|
1822 |
gr.Markdown(f"**Current Method**: {method_description}")
|
|
|
1839 |
outputs=[intensity_output, confidence_output]
|
1840 |
)
|
1841 |
|
1842 |
+
prediction_info_text = """
|
1843 |
+
### Prediction Features:
|
1844 |
+
- Environmental Analysis: Considers ENSO, latitude, seasonality
|
1845 |
+
- Real-time Capable: Predictions in milliseconds
|
1846 |
+
- Confidence Scoring: Uncertainty quantification included
|
1847 |
+
- Robust Fallbacks: Works with or without deep learning libraries
|
|
|
1848 |
|
1849 |
+
### Interpretation Guide:
|
1850 |
+
- 25-33 kt: Tropical Depression (TD)
|
1851 |
+
- 34-63 kt: Tropical Storm (TS)
|
1852 |
+
- 64+ kt: Typhoon categories (C1-C5)
|
1853 |
+
- 100+ kt: Major typhoon (C3+)
|
1854 |
+
"""
|
1855 |
+
gr.Markdown(prediction_info_text)
|
1856 |
+
|
1857 |
+
with gr.Tab("Track Visualization"):
|
1858 |
with gr.Row():
|
1859 |
start_year = gr.Number(label="Start Year", value=2020)
|
1860 |
start_month = gr.Dropdown(label="Start Month", choices=list(range(1, 13)), value=1)
|
|
|
1871 |
outputs=[tracks_plot, typhoon_count]
|
1872 |
)
|
1873 |
|
1874 |
+
with gr.Tab("Wind Analysis"):
|
1875 |
with gr.Row():
|
1876 |
wind_start_year = gr.Number(label="Start Year", value=2020)
|
1877 |
wind_start_month = gr.Dropdown(label="Start Month", choices=list(range(1, 13)), value=1)
|
|
|
1888 |
outputs=[wind_scatter, wind_regression_results]
|
1889 |
)
|
1890 |
|
1891 |
+
with gr.Tab("Pressure Analysis"):
|
1892 |
with gr.Row():
|
1893 |
pressure_start_year = gr.Number(label="Start Year", value=2020)
|
1894 |
pressure_start_month = gr.Dropdown(label="Start Month", choices=list(range(1, 13)), value=1)
|
|
|
1905 |
outputs=[pressure_scatter, pressure_regression_results]
|
1906 |
)
|
1907 |
|
1908 |
+
with gr.Tab("Longitude Analysis"):
|
1909 |
with gr.Row():
|
1910 |
lon_start_year = gr.Number(label="Start Year", value=2020)
|
1911 |
lon_start_month = gr.Dropdown(label="Start Month", choices=list(range(1, 13)), value=1)
|
|
|
1923 |
outputs=[regression_plot, slopes_text, lon_regression_results]
|
1924 |
)
|
1925 |
|
1926 |
+
with gr.Tab("Enhanced Track Animation"):
|
1927 |
gr.Markdown("## High-Quality Storm Track Visualization (All Categories Including TD)")
|
1928 |
|
1929 |
with gr.Row():
|
|
|
1964 |
outputs=[video_output]
|
1965 |
)
|
1966 |
|
1967 |
+
animation_info_text = """
|
1968 |
### Enhanced Animation Features:
|
1969 |
+
- Full TD Support: Now displays Tropical Depressions (< 34 kt) in gray
|
1970 |
+
- 2025 Compatibility: Complete support for current year data
|
1971 |
+
- Enhanced Maps: Better cartographic projections with terrain features
|
1972 |
+
- Smart Scaling: Storm symbols scale dynamically with intensity
|
1973 |
+
- Real-time Info: Live position, time, and meteorological data display
|
1974 |
+
- Professional Styling: Publication-quality animations with proper legends
|
1975 |
+
- Optimized Export: Fast rendering with web-compatible video formats
|
1976 |
+
"""
|
1977 |
+
gr.Markdown(animation_info_text)
|
1978 |
|
1979 |
with gr.Tab("Data Statistics & Insights"):
|
1980 |
gr.Markdown("## Comprehensive Dataset Analysis")
|
|
|
2038 |
except Exception as e:
|
2039 |
gr.Markdown(f"Visualization error: {str(e)}")
|
2040 |
|
2041 |
+
# Enhanced statistics - FIXED formatting
|
2042 |
total_storms = len(typhoon_data['SID'].unique()) if 'SID' in typhoon_data.columns else 0
|
2043 |
total_records = len(typhoon_data)
|
2044 |
|
|
|
2081 |
td_storms = ts_storms = typhoon_storms = 0
|
2082 |
td_percentage = 0
|
2083 |
|
2084 |
+
# Create statistics text safely
|
2085 |
+
stats_text = f"""
|
2086 |
### Enhanced Dataset Summary:
|
2087 |
+
- Total Unique Storms: {total_storms:,}
|
2088 |
+
- Total Track Records: {total_records:,}
|
2089 |
+
- Year Range: {year_range} ({years_covered} years)
|
2090 |
+
- Basins Available: {basins_available}
|
2091 |
+
- Average Storms/Year: {avg_storms_per_year:.1f}
|
2092 |
|
2093 |
### Storm Category Breakdown:
|
2094 |
+
- Tropical Depressions: {td_storms:,} storms ({td_percentage:.1f}%)
|
2095 |
+
- Tropical Storms: {ts_storms:,} storms
|
2096 |
+
- Typhoons (C1-C5): {typhoon_storms:,} storms
|
2097 |
|
2098 |
### New Platform Capabilities:
|
2099 |
+
- Complete TD Analysis - First platform to include comprehensive TD tracking
|
2100 |
+
- Advanced ML Clustering - DBSCAN pattern recognition with route visualization
|
2101 |
+
- Real-time Predictions - Physics-based and optional CNN intensity forecasting
|
2102 |
+
- 2025 Data Ready - Full compatibility with current season data
|
2103 |
+
- Enhanced Animations - Professional-quality storm track videos
|
2104 |
+
- Multi-basin Analysis - Comprehensive Pacific and Atlantic coverage
|
2105 |
|
2106 |
### Research Applications:
|
2107 |
- Climate change impact studies
|
|
|
2109 |
- Storm pattern classification
|
2110 |
- ENSO-typhoon relationship analysis
|
2111 |
- Intensity prediction model development
|
2112 |
+
"""
|
2113 |
+
gr.Markdown(stats_text)
|
2114 |
|
2115 |
return demo
|
2116 |
except Exception as e:
|
|
|
2192 |
plotly_color = enhanced_color_map.get(category, 'rgb(128,128,128)')
|
2193 |
matplotlib_color = get_matplotlib_color(category)
|
2194 |
|
2195 |
+
print(f"Wind: {wind:3d}kt -> {category:20s} -> Plotly: {plotly_color:15s} -> Matplotlib: {matplotlib_color}")
|
2196 |
|
2197 |
print("Color conversion test complete!")
|
2198 |
|
|
|
2208 |
print("Testing RGB to hex conversion...")
|
2209 |
for rgb_str in test_colors:
|
2210 |
hex_color = rgb_string_to_hex(rgb_str)
|
2211 |
+
print(f"{rgb_str:20s} -> {hex_color}")
|
2212 |
|
2213 |
print("RGB conversion test complete!")
|
2214 |
|