ziyuzhou02 commited on
Commit
347de80
Β·
verified Β·
1 Parent(s): d79ee7d

Deploy Space: update app.py

Browse files
Files changed (1) hide show
  1. app.py +128 -7
app.py CHANGED
@@ -1,5 +1,6 @@
1
  import json
2
  import os
 
3
  from pathlib import Path
4
 
5
  import gradio as gr
@@ -17,6 +18,11 @@ from src.utils import (
17
  dataset_section_title,
18
  get_grouped_dfs,
19
  group_datasets_by_domain,
 
 
 
 
 
20
  prepare_ranks_table,
21
  prepare_values_table,
22
  )
@@ -72,25 +78,55 @@ def _dataset_tables(grouped: dict, datasets: list[str]) -> tuple[list, list]:
72
  return values_tables, rank_tables
73
 
74
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
  def refresh_leaderboard() -> tuple:
76
  grouped = get_grouped_dfs(RESULTS_PATH)
77
  status = load_online_status(RESULTS_PATH)
78
  datasets = grouped["datasets"]
 
79
 
80
  outputs: list = [
81
- prepare_values_table(grouped["overall_values"]),
82
- prepare_ranks_table(grouped["overall_ranks"]),
 
 
 
83
  ]
84
  value_tables, rank_tables = _dataset_tables(grouped, datasets)
85
- outputs.extend(value_tables)
86
- outputs.extend(rank_tables)
87
- outputs.append(build_status_line(status))
88
  return tuple(outputs)
89
 
90
 
91
  grouped_initial = get_grouped_dfs(RESULTS_PATH)
92
  DATASETS: list[str] = grouped_initial["datasets"]
93
  DOMAIN_GROUPS = group_datasets_by_domain(DATASETS, RESULTS_PATH)
 
 
94
  INITIAL_OUTPUTS = refresh_leaderboard()
95
 
96
  demo = gr.Blocks(css=custom_css)
@@ -104,6 +140,7 @@ with demo:
104
  dataset_idx = 0
105
 
106
  with gr.Tabs(elem_classes="tab-buttons"):
 
107
  with gr.TabItem("Overall"):
108
  gr.Markdown(
109
  "Geometric mean of **absolute** metrics across all datasets. Lower is better.",
@@ -122,6 +159,36 @@ with demo:
122
  label="Ranks (average per-dataset rank, lower is better)",
123
  )
124
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
125
  for domain, domain_datasets in DOMAIN_GROUPS.items():
126
  with gr.TabItem(domain):
127
  for dataset in domain_datasets:
@@ -131,7 +198,7 @@ with demo:
131
  )
132
  dataset_value_dfs.append(
133
  gr.Dataframe(
134
- value=INITIAL_OUTPUTS[2 + dataset_idx],
135
  interactive=False,
136
  wrap=True,
137
  show_label=False,
@@ -143,12 +210,63 @@ with demo:
143
  )
144
  dataset_rank_dfs.append(
145
  gr.Dataframe(
146
- value=INITIAL_OUTPUTS[2 + len(DATASETS) + dataset_idx],
147
  interactive=False,
148
  wrap=True,
149
  show_label=False,
150
  )
151
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152
  dataset_idx += 1
153
 
154
  with gr.Accordion("About", open=False):
@@ -165,6 +283,9 @@ with demo:
165
  refresh_outputs = [
166
  overall_values_df,
167
  overall_ranks_df,
 
 
 
168
  *dataset_value_dfs,
169
  *dataset_rank_dfs,
170
  status,
 
1
  import json
2
  import os
3
+ import re
4
  from pathlib import Path
5
 
6
  import gradio as gr
 
18
  dataset_section_title,
19
  get_grouped_dfs,
20
  group_datasets_by_domain,
21
+ load_baseline_rank_history,
22
+ load_baseline_rank_history_weekly,
23
+ load_forecast_snapshots,
24
+ make_forecast_plot,
25
+ make_rank_trend_plot,
26
  prepare_ranks_table,
27
  prepare_values_table,
28
  )
 
78
  return values_tables, rank_tables
79
 
80
 
81
+ def _get_model_slugs(results_path: str) -> list[str]:
82
+ """Return subdirs of results_path that contain a forecasts/ subdirectory."""
83
+ slugs = []
84
+ for p in sorted(Path(results_path).iterdir()):
85
+ if p.is_dir() and (p / "forecasts").exists():
86
+ slugs.append(p.name)
87
+ return slugs
88
+
89
+
90
+ def _build_forecast_choices(results_path: str) -> dict[str, dict[str, dict]]:
91
+ """Build {model_slug: {dataset_name: snapshot}} for all models."""
92
+ choices: dict[str, dict[str, dict]] = {}
93
+ for slug in _get_model_slugs(results_path):
94
+ snaps = load_forecast_snapshots(results_path, slug)
95
+ if snaps:
96
+ choices[slug] = snaps
97
+ return choices
98
+
99
+
100
+ def _short_dataset_key(dataset_name: str) -> str:
101
+ """Extract the base dataset key from a leaderboard dataset name like 'ds/freq/term'."""
102
+ return dataset_name.split("/")[0]
103
+
104
+
105
  def refresh_leaderboard() -> tuple:
106
  grouped = get_grouped_dfs(RESULTS_PATH)
107
  status = load_online_status(RESULTS_PATH)
108
  datasets = grouped["datasets"]
109
+ daily_df = load_baseline_rank_history(RESULTS_PATH)
110
 
111
  outputs: list = [
112
+ prepare_values_table(grouped["overall_values"]), # [0]
113
+ prepare_ranks_table(grouped["overall_ranks"]), # [1]
114
+ daily_df, # [2] daily table
115
+ load_baseline_rank_history_weekly(RESULTS_PATH), # [3] weekly table
116
+ make_rank_trend_plot(daily_df), # [4] rank trend plot
117
  ]
118
  value_tables, rank_tables = _dataset_tables(grouped, datasets)
119
+ outputs.extend(value_tables) # [5 .. 5+N-1]
120
+ outputs.extend(rank_tables) # [5+N .. 5+2N-1]
121
+ outputs.append(build_status_line(status)) # [-1]
122
  return tuple(outputs)
123
 
124
 
125
  grouped_initial = get_grouped_dfs(RESULTS_PATH)
126
  DATASETS: list[str] = grouped_initial["datasets"]
127
  DOMAIN_GROUPS = group_datasets_by_domain(DATASETS, RESULTS_PATH)
128
+ FORECAST_CHOICES = _build_forecast_choices(RESULTS_PATH)
129
+ MODEL_SLUGS = list(FORECAST_CHOICES.keys())
130
  INITIAL_OUTPUTS = refresh_leaderboard()
131
 
132
  demo = gr.Blocks(css=custom_css)
 
140
  dataset_idx = 0
141
 
142
  with gr.Tabs(elem_classes="tab-buttons"):
143
+ # ── Overall Tab ──────────────────────────────────────────────────────
144
  with gr.TabItem("Overall"):
145
  gr.Markdown(
146
  "Geometric mean of **absolute** metrics across all datasets. Lower is better.",
 
159
  label="Ranks (average per-dataset rank, lower is better)",
160
  )
161
 
162
+ gr.Markdown(
163
+ "**Baseline daily rank history** Β· average rank across all datasets per day (lower is better)",
164
+ elem_classes="markdown-text",
165
+ )
166
+ baseline_history_df = gr.Dataframe(
167
+ value=INITIAL_OUTPUTS[2],
168
+ interactive=False,
169
+ wrap=True,
170
+ label="Baseline rank history β€” by day",
171
+ )
172
+ gr.Markdown(
173
+ "**Baseline weekly rank history** Β· average of daily ranks per ISO week (lower is better)",
174
+ elem_classes="markdown-text",
175
+ )
176
+ baseline_weekly_df = gr.Dataframe(
177
+ value=INITIAL_OUTPUTS[3],
178
+ interactive=False,
179
+ wrap=True,
180
+ label="Baseline rank history β€” by week",
181
+ )
182
+ gr.Markdown(
183
+ "**Baseline rank trend** Β· MASE / CRPS / MAE / RMSE rank over time",
184
+ elem_classes="markdown-text",
185
+ )
186
+ rank_trend_plot = gr.Plot(
187
+ value=INITIAL_OUTPUTS[4],
188
+ label="Rank trend over time",
189
+ )
190
+
191
+ # ── Domain Tabs ───────────────────────────────────────────────────────
192
  for domain, domain_datasets in DOMAIN_GROUPS.items():
193
  with gr.TabItem(domain):
194
  for dataset in domain_datasets:
 
198
  )
199
  dataset_value_dfs.append(
200
  gr.Dataframe(
201
+ value=INITIAL_OUTPUTS[5 + dataset_idx],
202
  interactive=False,
203
  wrap=True,
204
  show_label=False,
 
210
  )
211
  dataset_rank_dfs.append(
212
  gr.Dataframe(
213
+ value=INITIAL_OUTPUTS[5 + len(DATASETS) + dataset_idx],
214
  interactive=False,
215
  wrap=True,
216
  show_label=False,
217
  )
218
  )
219
+
220
+ # ── Forecast plot for this dataset ──────────────────────
221
+ if MODEL_SLUGS:
222
+ ds_key = _short_dataset_key(dataset)
223
+ # Find which models have a snapshot for this dataset
224
+ available_models = [
225
+ slug for slug in MODEL_SLUGS
226
+ if any(
227
+ _short_dataset_key(k) == ds_key
228
+ for k in FORECAST_CHOICES.get(slug, {})
229
+ )
230
+ ]
231
+ if available_models:
232
+ gr.Markdown(
233
+ "**Forecast: true vs predicted** Β· select model",
234
+ elem_classes="dataset-heading",
235
+ )
236
+ model_dd = gr.Dropdown(
237
+ choices=available_models,
238
+ value=available_models[0],
239
+ label="Model",
240
+ interactive=True,
241
+ )
242
+
243
+ def _get_initial_snapshot(slug, dk=ds_key):
244
+ snaps = FORECAST_CHOICES.get(slug, {})
245
+ for name, snap in snaps.items():
246
+ if _short_dataset_key(name) == dk:
247
+ return snap
248
+ return None
249
+
250
+ forecast_plot = gr.Plot(
251
+ value=make_forecast_plot(_get_initial_snapshot(available_models[0])),
252
+ label="True vs Predicted",
253
+ )
254
+
255
+ def _make_update_fn(dk):
256
+ def _update(slug):
257
+ snaps = FORECAST_CHOICES.get(slug, {})
258
+ for name, snap in snaps.items():
259
+ if _short_dataset_key(name) == dk:
260
+ return make_forecast_plot(snap)
261
+ return None
262
+ return _update
263
+
264
+ model_dd.change(
265
+ fn=_make_update_fn(ds_key),
266
+ inputs=[model_dd],
267
+ outputs=[forecast_plot],
268
+ )
269
+
270
  dataset_idx += 1
271
 
272
  with gr.Accordion("About", open=False):
 
283
  refresh_outputs = [
284
  overall_values_df,
285
  overall_ranks_df,
286
+ baseline_history_df,
287
+ baseline_weekly_df,
288
+ rank_trend_plot,
289
  *dataset_value_dfs,
290
  *dataset_rank_dfs,
291
  status,