Source code for tseda.visualization.base

"""
Shared style, palette, and helpers for tseda visualizations.

Classes / constants
-------------------
PALETTE : dict
    Brand colour map.
set_style()
    Apply tseda rcParams globally.
_make_fig_ax(ax, figsize, default_figsize)
    Internal helper — returns (fig, ax), creating a new figure when ax is None.
"""
from __future__ import annotations

from typing import Optional, Tuple

import matplotlib.pyplot as plt
import matplotlib as mpl
from matplotlib.figure import Figure
from matplotlib.axes import Axes

__all__ = ["PALETTE", "set_style"]

PALETTE: dict = {
    "dark":     "#2c3e50",
    "accent":   "#2980b9",
    "anomaly":  "#e74c3c",
    "seasonal": "#27ae60",
    "trend":    "#8e44ad",
    "neutral":  "#7f8c8d",
    "light":    "#ecf0f1",
    "warn":     "#e67e22",
}


[docs] def set_style() -> None: """Apply the tseda matplotlib style globally. Sets font size, grid style, and removes top/right spines. Safe to call multiple times. """ mpl.rcParams.update({ "font.size": 11, "axes.titlesize": 12, "axes.labelsize": 11, "xtick.labelsize": 10, "ytick.labelsize": 10, "axes.spines.top": False, "axes.spines.right": False, "axes.grid": True, "grid.alpha": 0.3, "grid.linestyle": "--", "figure.dpi": 100, "figure.facecolor": "white", "axes.facecolor": "white", })
def _make_fig_ax( ax: Optional[Axes], figsize: Optional[Tuple[float, float]], default_figsize: Tuple[float, float], ) -> Tuple[Figure, Axes]: """Return (fig, ax). Creates a new figure when *ax* is ``None``.""" if ax is None: fig, ax = plt.subplots(figsize=figsize or default_figsize) else: fig = ax.get_figure() if figsize is not None and fig is not None: fig.set_size_inches(figsize) return fig, ax # type: ignore[return-value] def _set_title(ax: Axes, title: Optional[str], default: str) -> None: ax.set_title(title if title is not None else default)