Source code for dartwork_mpl.style

"""Matplotlib style management utilities.

This module provides functions and classes for managing and applying
matplotlib styles from the package's style library.
"""

import json
from pathlib import Path

import matplotlib.pyplot as plt


[docs] def style_path(name: str) -> Path: """ Get the path to a style file. Parameters ---------- name : str Name of the style. Returns ------- Path Path to the style file. Raises ------ ValueError If the style is not found. """ path: Path = Path(__file__).parent / f"asset/mplstyle/{name}.mplstyle" if not path.exists(): raise ValueError(f"Not found style: {name}") return path
[docs] def list_styles() -> list[str]: """ List all available styles. Returns ------- list[str] List of style names. """ path: Path = Path(__file__).parent / "asset/mplstyle" return sorted([p.stem for p in path.glob("*.mplstyle")])
[docs] def load_style_dict(name: str) -> dict[str, float | str]: """ Load key, value pairs from a mplstyle file. Parameters ---------- name : str Name of the style. Returns ------- dict[str, float | str] Dictionary of style parameters. Values are converted to float if possible, otherwise kept as strings. """ # Load key, value pair from mplstyle files. path: Path = style_path(name) style_dict: dict[str, float | str] = {} with open(path) as f: for line in f: if line.strip().startswith("#"): continue if line.strip() == "": continue key: str = line.split(":")[0].strip() value: str = line.split(":")[1].split()[0].strip() try: value_float: float = float(value) style_dict[key] = value_float except ValueError: style_dict[key] = value return style_dict
[docs] class Style: """ A class for managing and applying multiple matplotlib styles. This class provides functionality to load style presets and apply multiple styles in sequence. Examples -------- >>> import dartwork_mpl as dm >>> dm.style.use("scientific") # Apply a preset >>> dm.style.stack(["base", "lang-kr"]) # Stack multiple styles """ def __init__(self) -> None: """Initialize Style instance and load presets.""" self.presets: dict[str, list[str]] = {} # Load presets self.load_presets()
[docs] @staticmethod def presets_path() -> Path: """ Get the path to the presets file. Returns ------- Path Path to the presets.json file containing style preset definitions. """ return Path(__file__).parent / "asset/mplstyle/presets.json"
[docs] def load_presets(self) -> None: """ Load style presets from the JSON file. This method reads the presets.json file and stores the preset definitions in the instance's presets attribute. """ with open(self.presets_path()) as f: self.presets = json.load(f)
[docs] @staticmethod def stack(style_names: list[str]) -> None: """ Stack multiple styles in order. This method applies multiple style files in sequence. Later styles override earlier ones for conflicting settings. Parameters ---------- style_names : list[str] List of style names to stack. Styles are applied in order, with later styles taking precedence. Examples -------- >>> import dartwork_mpl as dm >>> dm.style.stack(["base", "font-scientific", "lang-kr"]) """ plt.rcParams.update(plt.rcParamsDefault) plt.style.use(style_path(style_name) for style_name in style_names)
[docs] def use(self, preset_name: str) -> None: """ Apply a preset style configuration. This is the recommended way to apply styles. Presets are predefined combinations of styles optimized for specific use cases. Parameters ---------- preset_name : str Name of the preset to apply. Available presets: - "scientific": For academic papers - "investment": For investment reports - "presentation": For presentations - "scientific-kr": Scientific with Korean font - "investment-kr": Investment with Korean font - "presentation-kr": Presentation with Korean font Raises ------ KeyError If the preset name is not found in the presets dictionary. Examples -------- >>> import dartwork_mpl as dm >>> dm.style.use("scientific") >>> dm.style.use("presentation-kr") """ if preset_name not in self.presets: raise KeyError(f"Preset '{preset_name}' not found") self.stack(self.presets[preset_name])
[docs] def presets_dict(self) -> dict[str, list[str]]: """ Get all available presets as a dictionary. Returns ------- dict[str, list[str]] Dictionary mapping preset names to their style configuration lists. """ return dict(self.presets.items())
style: Style = Style()