Skip to content

Styling Context

Central configuration for fonts, colors, and styling options with proper bundled font management.

FontConfig dataclass

Configuration for fonts used in plots.

Source code in pyretailscience/plots/styles/styling_context.py
@dataclass
class FontConfig:
    """Configuration for fonts used in plots."""

    title_font: str = "poppins_semi_bold"
    title_size: float = 20
    label_font: str = "poppins_regular"
    label_size: float = 12
    tick_font: str = "poppins_regular"
    tick_size: float = 10
    source_font: str = "poppins_light_italic"
    source_size: float = 10

StylingContext

Central styling context that maintains bundled fonts as defaults but enables customization.

Source code in pyretailscience/plots/styles/styling_context.py
class StylingContext:
    """Central styling context that maintains bundled fonts as defaults but enables customization."""

    def __init__(self) -> None:
        """Initialize the styling context with default fonts and cache."""
        self.fonts = FontConfig()
        self._font_cache: dict[str, fm.FontProperties] = {}

        # Built-in font registry - maps names to bundled font files
        self._builtin_fonts = {
            "poppins_bold": f"{ASSETS_PATH}/fonts/Poppins-Bold.ttf",
            "poppins_semi_bold": f"{ASSETS_PATH}/fonts/Poppins-SemiBold.ttf",
            "poppins_regular": f"{ASSETS_PATH}/fonts/Poppins-Regular.ttf",
            "poppins_medium": f"{ASSETS_PATH}/fonts/Poppins-Medium.ttf",
            "poppins_light_italic": f"{ASSETS_PATH}/fonts/Poppins-LightItalic.ttf",
        }

    def get_font_properties(self, font_name: str) -> fm.FontProperties:
        """Get matplotlib FontProperties with flexible font resolution.

        This method resolves fonts in the following priority order:
        1. Check cache for previously loaded font
        2. Try to load from bundled fonts if font_name matches a built-in font
        3. Try to load as a system font family name

        Args:
            font_name (str): The name of the font to load. Can be:
                - A built-in font name (e.g., 'poppins_regular')
                - A system font family name (e.g., 'Arial', 'Times New Roman')

        Returns:
            fm.FontProperties: A matplotlib FontProperties object that can be used
                for text rendering.
        """
        if font_name in self._font_cache:
            return self._font_cache[font_name]

        # Try to load built-in bundled fonts first
        if font_name in self._builtin_fonts:
            font_props = fm.FontProperties(fname=self._builtin_fonts[font_name])
            self._font_cache[font_name] = font_props
            return font_props

        # Try to load as system font family
        font_props = fm.FontProperties(family=font_name)
        self._font_cache[font_name] = font_props
        return font_props

    def get_color_generators(self) -> dict[str, Generator[str, None, None]] | None:
        """Get color generators for plots.

        Returns:
            Dictionary with 'single' and 'multi' color generators if custom colors are set,
            or None to fall back to default tailwind colors.
            Enterprise plugins override this method to provide custom color generators.
        """
        # Base implementation returns None - enterprise plugins will override this
        return None

__init__()

Initialize the styling context with default fonts and cache.

Source code in pyretailscience/plots/styles/styling_context.py
def __init__(self) -> None:
    """Initialize the styling context with default fonts and cache."""
    self.fonts = FontConfig()
    self._font_cache: dict[str, fm.FontProperties] = {}

    # Built-in font registry - maps names to bundled font files
    self._builtin_fonts = {
        "poppins_bold": f"{ASSETS_PATH}/fonts/Poppins-Bold.ttf",
        "poppins_semi_bold": f"{ASSETS_PATH}/fonts/Poppins-SemiBold.ttf",
        "poppins_regular": f"{ASSETS_PATH}/fonts/Poppins-Regular.ttf",
        "poppins_medium": f"{ASSETS_PATH}/fonts/Poppins-Medium.ttf",
        "poppins_light_italic": f"{ASSETS_PATH}/fonts/Poppins-LightItalic.ttf",
    }

get_color_generators()

Get color generators for plots.

Returns:

Type Description
dict[str, Generator[str, None, None]] | None

Dictionary with 'single' and 'multi' color generators if custom colors are set,

dict[str, Generator[str, None, None]] | None

or None to fall back to default tailwind colors.

dict[str, Generator[str, None, None]] | None

Enterprise plugins override this method to provide custom color generators.

Source code in pyretailscience/plots/styles/styling_context.py
def get_color_generators(self) -> dict[str, Generator[str, None, None]] | None:
    """Get color generators for plots.

    Returns:
        Dictionary with 'single' and 'multi' color generators if custom colors are set,
        or None to fall back to default tailwind colors.
        Enterprise plugins override this method to provide custom color generators.
    """
    # Base implementation returns None - enterprise plugins will override this
    return None

get_font_properties(font_name)

Get matplotlib FontProperties with flexible font resolution.

This method resolves fonts in the following priority order: 1. Check cache for previously loaded font 2. Try to load from bundled fonts if font_name matches a built-in font 3. Try to load as a system font family name

Parameters:

Name Type Description Default
font_name str

The name of the font to load. Can be: - A built-in font name (e.g., 'poppins_regular') - A system font family name (e.g., 'Arial', 'Times New Roman')

required

Returns:

Type Description
FontProperties

fm.FontProperties: A matplotlib FontProperties object that can be used for text rendering.

Source code in pyretailscience/plots/styles/styling_context.py
def get_font_properties(self, font_name: str) -> fm.FontProperties:
    """Get matplotlib FontProperties with flexible font resolution.

    This method resolves fonts in the following priority order:
    1. Check cache for previously loaded font
    2. Try to load from bundled fonts if font_name matches a built-in font
    3. Try to load as a system font family name

    Args:
        font_name (str): The name of the font to load. Can be:
            - A built-in font name (e.g., 'poppins_regular')
            - A system font family name (e.g., 'Arial', 'Times New Roman')

    Returns:
        fm.FontProperties: A matplotlib FontProperties object that can be used
            for text rendering.
    """
    if font_name in self._font_cache:
        return self._font_cache[font_name]

    # Try to load built-in bundled fonts first
    if font_name in self._builtin_fonts:
        font_props = fm.FontProperties(fname=self._builtin_fonts[font_name])
        self._font_cache[font_name] = font_props
        return font_props

    # Try to load as system font family
    font_props = fm.FontProperties(family=font_name)
    self._font_cache[font_name] = font_props
    return font_props

get_styling_context()

Get the global styling context instance.

Source code in pyretailscience/plots/styles/styling_context.py
def get_styling_context() -> StylingContext:
    """Get the global styling context instance."""
    return _styling_context

update_styling_context(context)

Update the global styling context (used by enterprise plugins).

Source code in pyretailscience/plots/styles/styling_context.py
def update_styling_context(context: StylingContext) -> None:
    """Update the global styling context (used by enterprise plugins)."""
    global _styling_context  # noqa:PLW0603
    _styling_context = context