bitsofchris's picture
Add NWS client, Toto forecast wrapper, and Gradio app
b00faa3
"""Plotly figure builders for the Toto weather demo."""
from __future__ import annotations
import pandas as pd
import plotly.graph_objects as go
from .forecast import TotoForecast
def metric_figure(
history: pd.Series,
toto: TotoForecast,
nws: pd.Series | None,
title: str,
y_label: str,
now: pd.Timestamp | None = None,
) -> go.Figure:
fig = go.Figure()
# Past actuals
fig.add_trace(
go.Scatter(
x=history.index, y=history.values,
name="Ecowitt (past)", mode="lines",
line=dict(color="#222", width=2),
)
)
# Toto p10–p90 band
fig.add_trace(
go.Scatter(
x=list(toto.p90.index) + list(toto.p10.index[::-1]),
y=list(toto.p90.values) + list(toto.p10.values[::-1]),
fill="toself", fillcolor="rgba(31,119,180,0.18)",
line=dict(width=0), hoverinfo="skip",
name="Toto 10–90% interval",
)
)
# Toto median
fig.add_trace(
go.Scatter(
x=toto.median.index, y=toto.median.values,
name="Toto median", mode="lines",
line=dict(color="#1f77b4", width=2, dash="dash"),
)
)
if nws is not None and not nws.empty:
fig.add_trace(
go.Scatter(
x=nws.index, y=nws.values,
name="NWS forecast", mode="lines",
line=dict(color="#d62728", width=2, dash="dot"),
)
)
if now is not None:
fig.add_vline(x=now, line=dict(color="#888", dash="dot", width=1))
fig.update_layout(
title=title,
xaxis_title="Time (UTC)",
yaxis_title=y_label,
hovermode="x unified",
margin=dict(l=40, r=20, t=50, b=40),
legend=dict(orientation="h", yanchor="bottom", y=1.02, xanchor="right", x=1),
)
return fig