bitsofchris Claude Opus 4.7 (1M context) commited on
Commit
616bb9e
Β·
1 Parent(s): d6d17d4

Reorder layout, residual to 1h, scoreboard temp+humidity only

Browse files

- Drop pressure from the scoreboard table (NWS doesn't forecast pressure
so there's nothing to compare).
- Residual chart now pinned to 1 h-ahead so it matches the first row of
the table.
- Move the scoreboard + residual section below the weekly forecast
chart, under a new 'πŸ† How has each model done so far?' heading. The
page now opens with the forecast story (hero β†’ comparison β†’ radar β†’
72h chart) and only after that asks 'and how well does it actually
do?'. The explainer accordions stay at the bottom.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Files changed (2) hide show
  1. app.py +8 -7
  2. src/weather_ui.py +1 -1
app.py CHANGED
@@ -281,9 +281,9 @@ def refresh():
281
  comparison_md = ""
282
  scoreboard = render_scoreboard(log_conn)
283
 
284
- # Residual chart β€” pinned to 3 h-ahead (the middle row of the scoreboard
285
- # table) so the picture matches one of the headline numbers.
286
- resid_df = forecast_log.residuals(log_conn, metric="temp_f", window_hours=48, lag_hours=3.0)
287
  resid_fig = residual_figure(resid_df) if not resid_df.empty else None
288
 
289
  persist.push_db_async()
@@ -292,10 +292,10 @@ def refresh():
292
 
293
  # --- scoreboard ----------------------------------------------------------
294
  SCOREBOARD_HORIZONS_H = [1, 3, 12]
 
295
  SCOREBOARD_METRICS = [
296
  ("temp_f", "Temperature", "Β°F"),
297
  ("humidity", "Humidity", "%"),
298
- ("pressure_inhg", "Pressure", "inHg"),
299
  ]
300
 
301
 
@@ -440,12 +440,13 @@ with gr.Blocks(title="Toto Weather Forecast", theme=gr.themes.Soft()) as demo:
440
  "<span style='opacity:0.55'>πŸ”„ Live data + forecast auto-refresh every 15 minutes.</span>"
441
  )
442
 
443
- scoreboard_md = gr.Markdown()
444
- residual_plot = gr.Plot(label="Forecast residual")
445
-
446
  gr.Markdown(f"### πŸ“… {VIEW_WEEK['label']}")
447
  week_plot = gr.Plot(label="Weekly")
448
 
 
 
 
 
449
  with gr.Accordion("How the scoreboard is calculated", open=False):
450
  gr.Markdown(
451
  "We score each model on **how close its prediction was to the actual Ecowitt reading** "
 
281
  comparison_md = ""
282
  scoreboard = render_scoreboard(log_conn)
283
 
284
+ # Residual chart β€” 1 h-ahead, matching the first row of the scoreboard
285
+ # table so the picture corresponds to the easiest headline number.
286
+ resid_df = forecast_log.residuals(log_conn, metric="temp_f", window_hours=48, lag_hours=1.0)
287
  resid_fig = residual_figure(resid_df) if not resid_df.empty else None
288
 
289
  persist.push_db_async()
 
292
 
293
  # --- scoreboard ----------------------------------------------------------
294
  SCOREBOARD_HORIZONS_H = [1, 3, 12]
295
+ # Pressure has no NWS counterpart, so the head-to-head scoreboard skips it.
296
  SCOREBOARD_METRICS = [
297
  ("temp_f", "Temperature", "Β°F"),
298
  ("humidity", "Humidity", "%"),
 
299
  ]
300
 
301
 
 
440
  "<span style='opacity:0.55'>πŸ”„ Live data + forecast auto-refresh every 15 minutes.</span>"
441
  )
442
 
 
 
 
443
  gr.Markdown(f"### πŸ“… {VIEW_WEEK['label']}")
444
  week_plot = gr.Plot(label="Weekly")
445
 
446
+ gr.Markdown("### πŸ† How has each model done so far?")
447
+ scoreboard_md = gr.Markdown()
448
+ residual_plot = gr.Plot(label="Forecast residual")
449
+
450
  with gr.Accordion("How the scoreboard is calculated", open=False):
451
  gr.Markdown(
452
  "We score each model on **how close its prediction was to the actual Ecowitt reading** "
src/weather_ui.py CHANGED
@@ -183,7 +183,7 @@ def emoji_strip_markdown(nws_df: pd.DataFrame, tz: str, n: int = 12) -> str:
183
 
184
  def residual_figure(
185
  df: pd.DataFrame,
186
- title: str = "Forecast residual β€” 3 h-ahead prediction minus Ecowitt actual, last 48 h (Β°F)",
187
  ) -> go.Figure:
188
  """Plot signed residuals over time for Toto and NWS. Zero is perfect."""
189
  fig = go.Figure()
 
183
 
184
  def residual_figure(
185
  df: pd.DataFrame,
186
+ title: str = "Forecast residual β€” 1 h-ahead prediction minus Ecowitt actual, last 48 h (Β°F)",
187
  ) -> go.Figure:
188
  """Plot signed residuals over time for Toto and NWS. Zero is perfect."""
189
  fig = go.Figure()