Source code for petres.viewers.viewer2d.matplotlib.theme

from __future__ import annotations

from dataclasses import dataclass
from typing import Literal


[docs] @dataclass(frozen=True) class Matplotlib2DViewerTheme: """Store visual configuration for 2D Matplotlib viewers. This dataclass centralizes figure, axes, grid, and typography defaults used by the 2D viewer layer. Values are intentionally conservative so they work well for both regular grids and irregular polygonal geometry. Parameters ---------- figure_size : tuple[float, float], default=(9.0, 7.0) Figure size in inches as ``(width, height)``. dpi : int, default=120 Figure resolution in dots per inch. constrained_layout : bool, default=True Whether Matplotlib constrained layout is enabled. background : str | tuple[float, float, float] | tuple[float, float, float, float], default="white" Axes background color accepted by Matplotlib. aspect : {"auto", "equal"}, default="equal" Aspect ratio mode passed to Matplotlib axes. margins : float, default=0.03 Relative axes margins. Must be non-negative. grid : bool, default=True Whether to show major grid lines. grid_alpha : float, default=0.18 Grid line alpha in the inclusive range ``[0.0, 1.0]``. grid_linestyle : str, default="--" Matplotlib line style string for grid lines. grid_linewidth : float, default=0.6 Grid line width in points. Must be non-negative. xlabel : str, default="X Axis" X-axis label text. ylabel : str, default="Y Axis" Y-axis label text. show_labels : bool, default=True Whether axis labels are rendered. title_fontsize : float, default=13.0 Font size used for plot titles. Must be positive. hide_top_right_spines : bool, default=True Whether top and right spines are hidden. tick_labelsize : float, default=10.0 Font size used for tick labels. Must be positive. Raises ------ ValueError If one or more numeric configuration fields are outside their valid ranges. Examples -------- >>> theme = Matplotlib2DViewerTheme(background="whitesmoke", aspect="auto") >>> theme.dpi 120 Notes ----- ``__init__`` is generated by ``dataclasses`` based on the declared fields. Runtime validation is performed in ``__post_init__``. """ # Figure figure_size: tuple[float, float] = (9.0, 7.0) dpi: int = 120 constrained_layout: bool = True # Axes background: str | tuple[float, float, float] | tuple[float, float, float, float] = "white" aspect: Literal["auto", "equal"] = "equal" margins: float = 0.03 # Grid grid: bool = False grid_alpha: float = 0.18 grid_linestyle: str = "--" grid_linewidth: float = 0.6 # Labels xlabel: str = "X Axis" ylabel: str = "Y Axis" show_labels: bool = True # Title title_fontsize: float = 13.0 # Spines / ticks hide_top_right_spines: bool = True tick_labelsize: float = 10.0
[docs] def __post_init__(self) -> None: """Validate numeric theme values after dataclass initialization. Raises ------ ValueError If ``margins`` or ``grid_linewidth`` is negative, if ``grid_alpha`` is outside ``[0.0, 1.0]``, if ``dpi`` is not strictly positive, or if ``title_fontsize`` / ``tick_labelsize`` is not strictly positive. """ if self.margins < 0.0: raise ValueError("margins must be >= 0.0") if not 0.0 <= self.grid_alpha <= 1.0: raise ValueError("grid_alpha must be within [0.0, 1.0]") if self.grid_linewidth < 0.0: raise ValueError("grid_linewidth must be >= 0.0") if self.dpi <= 0: raise ValueError("dpi must be > 0") if self.title_fontsize <= 0.0: raise ValueError("title_fontsize must be > 0.0") if self.tick_labelsize <= 0.0: raise ValueError("tick_labelsize must be > 0.0")