Source code for pyedautils.plots.solar

"""Solar-influence plot (see :mod:`pyedautils.data_prep.solar_influence`)."""

from typing import Optional

import pandas as pd
import plotly.graph_objects as go

COLOR_TEMP = "#0D7377"
COLOR_SOLAR = "#FBC02D"
COLOR_EVENT = "#E53935"


[docs] def plot_solar_influence( data: pd.DataFrame, room_col: str = "t_room", radiation_col: str = "solar", event_col: Optional[str] = None, title: str = "Solar Influence", temp_label: str = "Room temperature (°C)", radiation_label: str = "Global radiation (W/m²)", height: int = 360, ) -> go.Figure: """Dual-axis time series of room temperature and global radiation. Room temperature is drawn on the left axis, global radiation on the right axis. Optional steep-rise events are marked with triangles. Args: data: DataFrame indexed by timestamp (or with a ``timestamp`` column) containing the room-temperature and radiation columns. room_col: Room-temperature column. Default ``"t_room"``. radiation_col: Global-radiation column. Default ``"solar"``. event_col: Optional boolean column flagging steep-rise events; flagged rows are overlaid as triangles. Default *None*. title: Plot title. temp_label: Left y-axis label. radiation_label: Right y-axis label. height: Figure height in pixels. Default 360. Returns: go.Figure: Plotly dual-axis figure. """ df = data.copy() if "timestamp" in df.columns: df = df.set_index("timestamp") df.index = pd.to_datetime(df.index) fig = go.Figure() fig.add_trace(go.Scattergl( x=df.index, y=df[radiation_col], mode="lines", line=dict(color=COLOR_SOLAR, width=0.8), name="Global radiation", yaxis="y2", opacity=0.6, hovertemplate="%{x}<br>%{y:.0f} W/m²<extra></extra>", )) fig.add_trace(go.Scattergl( x=df.index, y=df[room_col], mode="lines", line=dict(color=COLOR_TEMP, width=1.2), name="Room temperature", hovertemplate="%{x}<br>%{y:.1f} °C<extra></extra>", )) if event_col is not None and event_col in df.columns: events = df[df[event_col].astype(bool)] if not events.empty: fig.add_trace(go.Scattergl( x=events.index, y=events[room_col], mode="markers", marker=dict(color=COLOR_EVENT, size=8, symbol="triangle-up"), name="Steep-rise event", hovertemplate="%{x}<br>%{y:.1f} °C<extra></extra>", )) fig.update_layout( title_text=f"<b>{title}</b>", title_font=dict(size=20), title_x=0.5, template="plotly_white", height=height, margin=dict(l=10, r=10, t=50, b=10), yaxis=dict(title=temp_label), yaxis2=dict(title=radiation_label, overlaying="y", side="right", showgrid=False), showlegend=True, legend=dict(orientation="h", yanchor="bottom", y=1.02, xanchor="left", x=0), hovermode="x unified", ) return fig