Source code for wraquant.viz.themes

"""Consistent theming for wraquant visualizations.

Provides a clean, professional dark-on-white style and a named color
palette used across all plotting functions.
"""

from __future__ import annotations

from typing import TYPE_CHECKING, Any

from wraquant.core.decorators import requires_extra

if TYPE_CHECKING:
    import matplotlib.axes
    import matplotlib.figure

# ---------------------------------------------------------------------------
# Named color palette
# ---------------------------------------------------------------------------

COLORS: dict[str, str] = {
    "primary": "#1f77b4",
    "secondary": "#ff7f0e",
    "positive": "#2ca02c",
    "negative": "#d62728",
    "neutral": "#7f7f7f",
    "accent": "#9467bd",
    "info": "#17becf",
    "warning": "#bcbd22",
    "drawdown": "#d62728",
    "benchmark": "#ff7f0e",
    "fill": "#1f77b4",
}


# ---------------------------------------------------------------------------
# Style helpers
# ---------------------------------------------------------------------------


[docs] @requires_extra("viz") def set_wraquant_style() -> None: """Apply a clean, professional dark-on-white matplotlib style via rcParams. This modifies the global matplotlib rcParams so that all subsequent plots use the wraquant house style. Call once at the start of a session or notebook. Returns: None """ import matplotlib.pyplot as plt style: dict[str, Any] = { # Figure "figure.figsize": (12, 6), "figure.dpi": 100, "figure.facecolor": "white", "figure.edgecolor": "white", # Axes "axes.facecolor": "white", "axes.edgecolor": "#cccccc", "axes.labelcolor": "#333333", "axes.titlesize": 14, "axes.titleweight": "bold", "axes.labelsize": 11, "axes.grid": True, "axes.spines.top": False, "axes.spines.right": False, # Grid "grid.color": "#e0e0e0", "grid.linewidth": 0.5, "grid.alpha": 0.7, # Lines "lines.linewidth": 1.5, "lines.antialiased": True, # Ticks "xtick.labelsize": 10, "ytick.labelsize": 10, "xtick.color": "#333333", "ytick.color": "#333333", # Legend "legend.fontsize": 10, "legend.framealpha": 0.8, "legend.edgecolor": "#cccccc", # Font "font.family": "sans-serif", "font.size": 11, # Savefig "savefig.dpi": 150, "savefig.bbox": "tight", } plt.rcParams.update(style)
[docs] @requires_extra("viz") def apply_theme( fig: matplotlib.figure.Figure, ax: matplotlib.axes.Axes, ) -> None: """Apply the wraquant visual theme to an existing figure and axes. Parameters: fig: The matplotlib Figure to style. ax: The matplotlib Axes to style. Returns: None """ fig.set_facecolor("white") fig.set_edgecolor("white") ax.set_facecolor("white") ax.spines["top"].set_visible(False) ax.spines["right"].set_visible(False) ax.spines["left"].set_color("#cccccc") ax.spines["bottom"].set_color("#cccccc") ax.tick_params(colors="#333333") ax.xaxis.label.set_color("#333333") ax.yaxis.label.set_color("#333333") ax.title.set_color("#333333") ax.grid(True, color="#e0e0e0", linewidth=0.5, alpha=0.7)