@@ -96,6 +96,8 @@ def init_session_state():
9696 st .session_state .merged_metrics_df = None
9797 if "fetch_time_stats" not in st .session_state :
9898 st .session_state .fetch_time_stats = ""
99+ if "t0_coverage" not in st .session_state :
100+ st .session_state .t0_coverage = None
99101 if "locked_params" not in st .session_state :
100102 st .session_state .locked_params = None
101103
@@ -156,9 +158,38 @@ async def async_dp_forecast_page() -> None:
156158 f"in `{ fetch_duration :.2f} ` seconds."
157159 )
158160
161+ # Work out which requested t0s actually came back with data. A t0 that the
162+ # Data Platform has no forecast for returns no rows (silently), so the chart's
163+ # time axis only spans the t0s that did return — surface that here rather than
164+ # leaving it looking like the axis is wrong.
165+ requested_t0s = cfg .t0s or []
166+ if requested_t0s and not df_forecast .empty :
167+ returned_t0s = set (df_forecast ["initialization_timestamp_utc" ])
168+ missing = [t0 for t0 in requested_t0s if t0 not in returned_t0s ]
169+ st .session_state .t0_coverage = {
170+ "requested" : len (requested_t0s ),
171+ "returned" : len (requested_t0s ) - len (missing ),
172+ "earliest_returned" : (
173+ min (returned_t0s ) if returned_t0s else None
174+ ),
175+ }
176+ else :
177+ st .session_state .t0_coverage = None
178+
159179 if st .session_state .fetch_time_stats :
160180 st .success (st .session_state .fetch_time_stats )
161181
182+ coverage = st .session_state .get ("t0_coverage" )
183+ if coverage and coverage ["returned" ] < coverage ["requested" ]:
184+ earliest = coverage ["earliest_returned" ]
185+ earliest_str = earliest .strftime ("%Y-%m-%d %H:%M" ) if earliest else "n/a"
186+ st .warning (
187+ f"Only `{ coverage ['returned' ]} ` of `{ coverage ['requested' ]} ` selected t0s "
188+ f"returned forecast data (earliest with data: { earliest_str } UTC). "
189+ "The time axis spans just those — the Data Platform returned nothing for the "
190+ "rest."
191+ )
192+
162193 # Ensure we have data before trying to plot
163194 if (
164195 st .session_state .forecast_df is not None
0 commit comments