File size: 1,874 Bytes
b00faa3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
"""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