Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -18,6 +18,7 @@ import cartopy.feature as cfeature
|
|
| 18 |
import plotly.graph_objects as go
|
| 19 |
import plotly.express as px
|
| 20 |
from plotly.subplots import make_subplots
|
|
|
|
| 21 |
from sklearn.manifold import TSNE
|
| 22 |
from sklearn.cluster import DBSCAN
|
| 23 |
from sklearn.preprocessing import StandardScaler
|
|
@@ -47,6 +48,7 @@ logging.basicConfig(
|
|
| 47 |
parser = argparse.ArgumentParser(description='Typhoon Analysis Dashboard')
|
| 48 |
parser.add_argument('--data_path', type=str, default=os.getcwd(), help='Path to the data directory')
|
| 49 |
args = parser.parse_args()
|
|
|
|
| 50 |
|
| 51 |
# Update data paths for Huggingface Spaces
|
| 52 |
TEMP_DIR = tempfile.gettempdir()
|
|
@@ -55,7 +57,7 @@ DATA_PATH = os.environ.get('DATA_PATH', TEMP_DIR)
|
|
| 55 |
# Ensure directory exists
|
| 56 |
os.makedirs(DATA_PATH, exist_ok=True)
|
| 57 |
|
| 58 |
-
#
|
| 59 |
ONI_DATA_PATH = os.path.join(DATA_PATH, 'oni_data.csv')
|
| 60 |
TYPHOON_DATA_PATH = os.path.join(DATA_PATH, 'processed_typhoon_data.csv')
|
| 61 |
MERGED_DATA_CSV = os.path.join(DATA_PATH, 'merged_typhoon_era5_data.csv')
|
|
@@ -115,95 +117,7 @@ regions = {
|
|
| 115 |
"Hong Kong": {"lat_min": 21.5, "lat_max": 23, "lon_min": 113, "lon_max": 115},
|
| 116 |
"Philippines": {"lat_min": 5, "lat_max": 21, "lon_min": 115, "lon_max": 130}
|
| 117 |
}
|
| 118 |
-
# Add these functions near the top of the file after imports
|
| 119 |
-
# After your imports section but before any other code, add:
|
| 120 |
|
| 121 |
-
# -----------------------------
|
| 122 |
-
# Sample Data Generation
|
| 123 |
-
# -----------------------------
|
| 124 |
-
def generate_sample_oni_data():
|
| 125 |
-
"""Generate sample ONI data"""
|
| 126 |
-
years = range(1950, 2024)
|
| 127 |
-
months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
|
| 128 |
-
data = {'Year': list(years)}
|
| 129 |
-
|
| 130 |
-
# Generate random ONI values between -2.5 and 2.5
|
| 131 |
-
np.random.seed(42) # For reproducibility
|
| 132 |
-
for month in months:
|
| 133 |
-
data[month] = np.round(np.random.uniform(-2.5, 2.5, len(years)), 1)
|
| 134 |
-
|
| 135 |
-
df = pd.DataFrame(data)
|
| 136 |
-
df.to_csv(ONI_DATA_PATH, index=False)
|
| 137 |
-
logging.info(f"Generated sample ONI data and saved to {ONI_DATA_PATH}")
|
| 138 |
-
return df
|
| 139 |
-
|
| 140 |
-
def generate_sample_typhoon_data():
|
| 141 |
-
"""Generate sample typhoon data"""
|
| 142 |
-
# Create sample data with realistic values
|
| 143 |
-
np.random.seed(42)
|
| 144 |
-
|
| 145 |
-
# Generate 100 sample typhoons
|
| 146 |
-
n_typhoons = 100
|
| 147 |
-
n_points_per_typhoon = 20
|
| 148 |
-
|
| 149 |
-
data = {
|
| 150 |
-
'SID': [],
|
| 151 |
-
'ISO_TIME': [],
|
| 152 |
-
'NAME': [],
|
| 153 |
-
'SEASON': [],
|
| 154 |
-
'LAT': [],
|
| 155 |
-
'LON': [],
|
| 156 |
-
'USA_WIND': [],
|
| 157 |
-
'USA_PRES': []
|
| 158 |
-
}
|
| 159 |
-
|
| 160 |
-
# Basin prefixes and sample names
|
| 161 |
-
basin_prefixes = ['WP', 'EP', 'NA']
|
| 162 |
-
typhoon_names = ['HAIYAN', 'YOLANDA', 'MANGKHUT', 'YUTU', 'HAGIBIS', 'MERANTI',
|
| 163 |
-
'MEGI', 'HAGUPIT', 'MAYSAK', 'HATO', 'NEPARTAK', 'SOUDELOR']
|
| 164 |
-
|
| 165 |
-
# Generate data
|
| 166 |
-
for i in range(n_typhoons):
|
| 167 |
-
basin = np.random.choice(basin_prefixes)
|
| 168 |
-
year = np.random.randint(1980, 2024)
|
| 169 |
-
name = np.random.choice(typhoon_names)
|
| 170 |
-
sid = f"{basin}{year}{i:02d}"
|
| 171 |
-
|
| 172 |
-
# Starting position
|
| 173 |
-
start_lon = np.random.uniform(120, 170)
|
| 174 |
-
start_lat = np.random.uniform(5, 30)
|
| 175 |
-
|
| 176 |
-
# Generate track points
|
| 177 |
-
for j in range(n_points_per_typhoon):
|
| 178 |
-
# Time progression
|
| 179 |
-
date = datetime(year, np.random.randint(6, 11), np.random.randint(1, 28),
|
| 180 |
-
np.random.randint(0, 24))
|
| 181 |
-
date += timedelta(hours=j*6) # 6-hour intervals
|
| 182 |
-
|
| 183 |
-
# Position progression (typically moves northwest in WP)
|
| 184 |
-
lon = start_lon - j * np.random.uniform(0.3, 0.8)
|
| 185 |
-
lat = start_lat + j * np.random.uniform(0.2, 0.5)
|
| 186 |
-
|
| 187 |
-
# Intensity progression (typically intensifies then weakens)
|
| 188 |
-
intensity_factor = min(1.0, j/(n_points_per_typhoon/2)) if j < n_points_per_typhoon/2 else \
|
| 189 |
-
1.0 - min(1.0, (j-n_points_per_typhoon/2)/(n_points_per_typhoon/2))
|
| 190 |
-
wind = np.random.randint(30, 150) * intensity_factor
|
| 191 |
-
pressure = 1010 - (wind * 0.75) # Approximate relationship
|
| 192 |
-
|
| 193 |
-
# Add to data dict
|
| 194 |
-
data['SID'].append(sid)
|
| 195 |
-
data['ISO_TIME'].append(date)
|
| 196 |
-
data['NAME'].append(name)
|
| 197 |
-
data['SEASON'].append(year)
|
| 198 |
-
data['LAT'].append(lat)
|
| 199 |
-
data['LON'].append(lon)
|
| 200 |
-
data['USA_WIND'].append(wind)
|
| 201 |
-
data['USA_PRES'].append(pressure)
|
| 202 |
-
|
| 203 |
-
df = pd.DataFrame(data)
|
| 204 |
-
df.to_csv(TYPHOON_DATA_PATH, index=False)
|
| 205 |
-
logging.info(f"Generated sample typhoon data and saved to {TYPHOON_DATA_PATH}")
|
| 206 |
-
return df
|
| 207 |
# -----------------------------
|
| 208 |
# ONI and Typhoon Data Functions
|
| 209 |
# -----------------------------
|
|
@@ -248,16 +162,18 @@ def update_oni_data():
|
|
| 248 |
os.remove(temp_file)
|
| 249 |
|
| 250 |
def load_data(oni_path, typhoon_path):
|
| 251 |
-
|
| 252 |
-
|
| 253 |
-
|
| 254 |
-
|
| 255 |
-
|
| 256 |
-
|
| 257 |
-
|
| 258 |
-
|
| 259 |
-
|
| 260 |
-
|
|
|
|
|
|
|
| 261 |
|
| 262 |
def process_oni_data(oni_data):
|
| 263 |
oni_long = oni_data.melt(id_vars=['Year'], var_name='Month', value_name='ONI')
|
|
@@ -1055,4 +971,3 @@ with gr.Blocks(title="Typhoon Analysis Dashboard") as demo:
|
|
| 1055 |
outputs=[tsne_plot, routes_plot, stats_plot, cluster_info])
|
| 1056 |
|
| 1057 |
demo.launch(share=True)
|
| 1058 |
-
|
|
|
|
| 18 |
import plotly.graph_objects as go
|
| 19 |
import plotly.express as px
|
| 20 |
from plotly.subplots import make_subplots
|
| 21 |
+
|
| 22 |
from sklearn.manifold import TSNE
|
| 23 |
from sklearn.cluster import DBSCAN
|
| 24 |
from sklearn.preprocessing import StandardScaler
|
|
|
|
| 48 |
parser = argparse.ArgumentParser(description='Typhoon Analysis Dashboard')
|
| 49 |
parser.add_argument('--data_path', type=str, default=os.getcwd(), help='Path to the data directory')
|
| 50 |
args = parser.parse_args()
|
| 51 |
+
DATA_PATH = args.data_path
|
| 52 |
|
| 53 |
# Update data paths for Huggingface Spaces
|
| 54 |
TEMP_DIR = tempfile.gettempdir()
|
|
|
|
| 57 |
# Ensure directory exists
|
| 58 |
os.makedirs(DATA_PATH, exist_ok=True)
|
| 59 |
|
| 60 |
+
# Update your file paths
|
| 61 |
ONI_DATA_PATH = os.path.join(DATA_PATH, 'oni_data.csv')
|
| 62 |
TYPHOON_DATA_PATH = os.path.join(DATA_PATH, 'processed_typhoon_data.csv')
|
| 63 |
MERGED_DATA_CSV = os.path.join(DATA_PATH, 'merged_typhoon_era5_data.csv')
|
|
|
|
| 117 |
"Hong Kong": {"lat_min": 21.5, "lat_max": 23, "lon_min": 113, "lon_max": 115},
|
| 118 |
"Philippines": {"lat_min": 5, "lat_max": 21, "lon_min": 115, "lon_max": 130}
|
| 119 |
}
|
|
|
|
|
|
|
| 120 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 121 |
# -----------------------------
|
| 122 |
# ONI and Typhoon Data Functions
|
| 123 |
# -----------------------------
|
|
|
|
| 162 |
os.remove(temp_file)
|
| 163 |
|
| 164 |
def load_data(oni_path, typhoon_path):
|
| 165 |
+
if not os.path.exists(typhoon_path):
|
| 166 |
+
logging.error(f"Typhoon data file not found: {typhoon_path}")
|
| 167 |
+
return pd.DataFrame(), pd.DataFrame()
|
| 168 |
+
try:
|
| 169 |
+
oni_data = pd.read_csv(oni_path)
|
| 170 |
+
typhoon_data = pd.read_csv(typhoon_path, low_memory=False)
|
| 171 |
+
typhoon_data['ISO_TIME'] = pd.to_datetime(typhoon_data['ISO_TIME'], errors='coerce')
|
| 172 |
+
typhoon_data = typhoon_data.dropna(subset=['ISO_TIME'])
|
| 173 |
+
return oni_data, typhoon_data
|
| 174 |
+
except Exception as e:
|
| 175 |
+
logging.error(f"Error loading data: {e}")
|
| 176 |
+
return pd.DataFrame(), pd.DataFrame()
|
| 177 |
|
| 178 |
def process_oni_data(oni_data):
|
| 179 |
oni_long = oni_data.melt(id_vars=['Year'], var_name='Month', value_name='ONI')
|
|
|
|
| 971 |
outputs=[tsne_plot, routes_plot, stats_plot, cluster_info])
|
| 972 |
|
| 973 |
demo.launch(share=True)
|
|
|