Create viz_components.py
Browse files- viz_components.py +85 -0
viz_components.py
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
import plotly.graph_objects as go
|
| 3 |
+
|
| 4 |
+
def make_gauge(aqi):
|
| 5 |
+
# Determine color
|
| 6 |
+
color = "#10b981"
|
| 7 |
+
if aqi > 50: color = "#f59e0b"
|
| 8 |
+
if aqi > 100: color = "#f97316"
|
| 9 |
+
if aqi > 150: color = "#ef4444"
|
| 10 |
+
|
| 11 |
+
fig = go.Figure(go.Indicator(
|
| 12 |
+
mode="gauge+number",
|
| 13 |
+
value=round(aqi, 1),
|
| 14 |
+
number={"font": {"size": 48, "color": "#0f172a", "family": "Inter, sans-serif", "weight": "bold"}},
|
| 15 |
+
gauge={
|
| 16 |
+
"axis": {"range": [0, 300], "visible": False},
|
| 17 |
+
"bar": {"color": color, "thickness": 0.3},
|
| 18 |
+
"bgcolor": "#f1f5f9",
|
| 19 |
+
"borderwidth": 0,
|
| 20 |
+
"steps": [
|
| 21 |
+
{"range": [0, 50], "color": "rgba(16, 185, 129, 0.1)"},
|
| 22 |
+
{"range": [50, 100], "color": "rgba(245, 158, 11, 0.1)"},
|
| 23 |
+
{"range": [100, 150], "color": "rgba(249, 115, 22, 0.1)"},
|
| 24 |
+
{"range": [150, 200], "color": "rgba(239, 68, 68, 0.1)"},
|
| 25 |
+
{"range": [200, 300], "color": "rgba(139, 92, 246, 0.1)"},
|
| 26 |
+
],
|
| 27 |
+
},
|
| 28 |
+
))
|
| 29 |
+
fig.update_layout(
|
| 30 |
+
height=240,
|
| 31 |
+
margin=dict(l=30, r=30, t=10, b=10),
|
| 32 |
+
paper_bgcolor="rgba(0,0,0,0)",
|
| 33 |
+
font=dict(family="Inter", color="#64748b"),
|
| 34 |
+
)
|
| 35 |
+
return fig
|
| 36 |
+
|
| 37 |
+
def make_plot(hist, fc):
|
| 38 |
+
n_hist = len(hist)
|
| 39 |
+
n_fc = len(fc)
|
| 40 |
+
x_hist = list(range(-n_hist, 0))
|
| 41 |
+
x_fc = list(range(0, n_fc))
|
| 42 |
+
|
| 43 |
+
fig = go.Figure()
|
| 44 |
+
|
| 45 |
+
# Clean background
|
| 46 |
+
fig.add_trace(go.Scatter(
|
| 47 |
+
x=x_hist, y=hist, name="Past",
|
| 48 |
+
line=dict(color="#10b981", width=4, shape='spline'),
|
| 49 |
+
mode="lines",
|
| 50 |
+
fill='tozeroy',
|
| 51 |
+
fillcolor='rgba(16, 185, 129, 0.05)',
|
| 52 |
+
hovertemplate="AQI %{y:.0f}<extra></extra>"
|
| 53 |
+
))
|
| 54 |
+
|
| 55 |
+
fig.add_trace(go.Scatter(
|
| 56 |
+
x=x_fc, y=fc, name="Forecast",
|
| 57 |
+
line=dict(color="#3b82f6", width=4, dash="dot", shape='spline'),
|
| 58 |
+
mode="lines",
|
| 59 |
+
hovertemplate="AQI %{y:.0f}<extra></extra>"
|
| 60 |
+
))
|
| 61 |
+
|
| 62 |
+
fig.update_layout(
|
| 63 |
+
template="plotly_white",
|
| 64 |
+
paper_bgcolor="rgba(0,0,0,0)",
|
| 65 |
+
plot_bgcolor="rgba(0,0,0,0)",
|
| 66 |
+
font=dict(color="#64748b", family="Inter"),
|
| 67 |
+
margin=dict(l=10, r=10, t=40, b=40),
|
| 68 |
+
legend=dict(orientation="h", yanchor="bottom", y=1.02, xanchor="right", x=1),
|
| 69 |
+
xaxis=dict(
|
| 70 |
+
showgrid=False,
|
| 71 |
+
zeroline=False,
|
| 72 |
+
showticklabels=True,
|
| 73 |
+
tickmode="array",
|
| 74 |
+
tickvals=[-24, 0, 24, 48],
|
| 75 |
+
ticktext=["-24h", "Now", "+24h", "+48h"]
|
| 76 |
+
),
|
| 77 |
+
yaxis=dict(
|
| 78 |
+
showgrid=True,
|
| 79 |
+
gridcolor="#f1f5f9",
|
| 80 |
+
zeroline=False,
|
| 81 |
+
side="right"
|
| 82 |
+
),
|
| 83 |
+
hovermode="x unified",
|
| 84 |
+
)
|
| 85 |
+
return fig
|