Source code for dartwork_mpl.util

"""Miscellaneous utilities for Matplotlib figure management.

Collects small helper functions that do not warrant their own module.
Also re-exports core functions that were moved to dedicated modules
for backward compatibility.
"""

from __future__ import annotations

# Re-exports for backward compatibility – these were moved to
# dedicated modules but many consumers still import from util.
from .annotation import arrow_axis, label_axes
from .io import save_and_show, save_formats, show
from .layout import get_bounding_box, set_xmargin, set_ymargin, simple_layout
from .prompt import copy_prompt, get_prompt, list_prompts, prompt_path
from .scale import fs, fw, lw

__all__ = [
    # Re-exports (moved modules)
    "fs",
    "fw",
    "lw",
    "simple_layout",
    "get_bounding_box",
    "set_xmargin",
    "set_ymargin",
    "save_formats",
    "save_and_show",
    "show",
    "label_axes",
    "arrow_axis",
    "prompt_path",
    "get_prompt",
    "list_prompts",
    "copy_prompt",
    # Residual helpers (kept here)
    "set_decimal",
    "mix_colors",
    "pseudo_alpha",
    "cm2in",
    "make_offset",
]

import matplotlib.colors as mcolors
from matplotlib.axes import Axes
from matplotlib.figure import Figure
from matplotlib.transforms import ScaledTranslation


[docs] def set_decimal(ax: Axes, xn: int | None = None, yn: int | None = None) -> None: """Fix the number of decimal places displayed on tick labels. Parameters ---------- ax : matplotlib.axes.Axes The Axes to modify. xn : int | None, optional Number of decimal places for x-axis tick labels. If None, the x-axis is left unchanged. yn : int | None, optional Number of decimal places for y-axis tick labels. If None, the y-axis is left unchanged. """ if xn is not None: xticks = ax.get_xticks() ax.set_xticks(xticks) ax.set_xticklabels([f"{x:.{xn}f}" for x in xticks]) if yn is not None: yticks = ax.get_yticks() ax.set_yticks(yticks) ax.set_yticklabels([f"{y:.{yn}f}" for y in yticks])
[docs] def mix_colors( color1: str | tuple[float, float, float], color2: str | tuple[float, float, float], alpha: float = 0.5, ) -> tuple[float, float, float]: """Blend two colors according to a given weight (alpha). Parameters ---------- color1 : str | tuple[float, float, float] First color to blend. Any format recognized by matplotlib. color2 : str | tuple[float, float, float] Second color to blend. alpha : float, optional Weight of the first color (between 0 and 1). Default is 0.5. Returns ------- tuple[float, float, float] RGB tuple of the blended result. """ color1 = mcolors.to_rgb(color1) color2 = mcolors.to_rgb(color2) r, g, b = ( alpha * c1 + (1 - alpha) * c2 for c1, c2 in zip(color1[:3], color2[:3], strict=False) ) return r, g, b
[docs] def pseudo_alpha( color: str | tuple[float, float, float], alpha: float = 1.0, background: str | tuple[float, float, float] = "white", ) -> tuple[float, float, float]: """Return an opaque RGB that simulates alpha transparency against a background. True alpha can cause darkening artifacts when lines overlap or cover images. This function blends the color with the background to produce a flat (opaque) color that visually mimics transparency. Parameters ---------- color : str | tuple[float, float, float] The target foreground color. alpha : float, optional Simulated opacity (0 to 1). Default is 1.0 (fully opaque). background : str | tuple[float, float, float], optional Background color to blend against. Default is "white". Returns ------- tuple[float, float, float] RGB tuple of the composited color. """ return mix_colors(color, background, alpha=alpha)
[docs] def cm2in(cm: float) -> float: """Convert centimeters to inches. Parameters ---------- cm : float Value in centimeters. Returns ------- float Equivalent value in inches. """ return cm / 2.54
[docs] def make_offset(x: float, y: float, fig: Figure) -> ScaledTranslation: """Create a translation offset transform for positioning figure elements. Parameters ---------- x : float Horizontal offset in points. y : float Vertical offset in points. fig : matplotlib.figure.Figure The Figure whose DPI scale is used. Returns ------- matplotlib.transforms.ScaledTranslation A translation transform that can be added to other transforms. """ dx, dy = x / 72, y / 72 offset = ScaledTranslation(dx, dy, fig.dpi_scale_trans) return offset