SPB Git

Repository Public

plotstyle.py 2.8 KB 69 lines python

1"""Matplotlib style for paper figures (static PDF). Follows the project dataviz rules: categorical hues in a fixed2order per system (never cycled), one axis per chart, thin marks, recessive grid/axes, text in ink tokens, direct3labels where they help. Palette = the validated reference instance (light mode)."""4from __future__ import annotations56import matplotlib as mpl78SURFACE = "#fcfcfb"9INK = "#0b0b0b"10INK2 = "#52514e"11GRID = "#e1e0d9"12AXIS = "#c3c2b7"13# fixed categorical order (slot → hue); systems are mapped to slots by name, never by rank14CATEGORICAL = ["#2a78d6", "#eb6834", "#1baf7a", "#eda100", "#e87ba4", "#008300"]15SYSTEM_SLOT = {"B0_identity": 0, "B1_generic_paraphrase": 1, "B2": 3, "M1": 2, "M2": 4, "M3": 5}16SEQUENTIAL_BLUE = ["#cde2fb", "#9ec5f4", "#6da7ec", "#3987e5", "#256abf", "#1c5cab", "#104281"]171819_ASSIGNED: dict[str, str] = {}20MARKERS = ["o", "s", "D", "^", "v", "P"]212223def assign_system_colors(systems: list[str]) -> dict[str, str]:24    """Fixed, order-stable assignment: baselines keep their slots (B0 blue, B1 orange, B2 yellow); other systems take25    the remaining slots in the order given. Hues are never generated; beyond 6 systems the extra ones reuse a slot and26    must be distinguished by marker (see MARKERS) and direct labels."""27    fixed = {"B0_identity": 0, "B1_generic_paraphrase": 1}28    used = set()29    out: dict[str, str] = {}30    for s in systems:31        if s in fixed:32            out[s] = CATEGORICAL[fixed[s]]33            used.add(fixed[s])34        elif s.startswith("B2"):35            out[s] = CATEGORICAL[3]36            used.add(3)37    free = [i for i in range(len(CATEGORICAL)) if i not in used]38    k = 039    for s in systems:40        if s not in out:41            out[s] = CATEGORICAL[free[k % len(free)]] if free else INK242            k += 143    _ASSIGNED.update(out)44    return out454647def system_color(name: str) -> str:48    if name in _ASSIGNED:49        return _ASSIGNED[name]50    for key, slot in SYSTEM_SLOT.items():51        if name == key or name.lower().startswith(key.lower()):52            return CATEGORICAL[slot]53    return INK2545556def system_marker(name: str, systems: list[str]) -> str:57    return MARKERS[systems.index(name) % len(MARKERS)] if name in systems else "o"585960def apply() -> None:61    mpl.rcParams.update({62        "figure.facecolor": SURFACE, "axes.facecolor": SURFACE, "savefig.facecolor": SURFACE,63        "font.family": "sans-serif", "font.size": 9, "axes.titlesize": 10, "axes.labelsize": 9, "legend.fontsize": 8,64        "text.color": INK, "axes.labelcolor": INK2, "xtick.color": INK2, "ytick.color": INK2,65        "axes.edgecolor": AXIS, "axes.linewidth": 0.6, "axes.spines.top": False, "axes.spines.right": False,66        "axes.grid": True, "grid.color": GRID, "grid.linewidth": 0.5, "axes.axisbelow": True,67        "lines.linewidth": 1.6, "lines.markersize": 4.5, "legend.frameon": False, "pdf.fonttype": 42,68    })69
Files main
Menu

Theme