| """Shared plotting style: seaborn modern look + vector PDF output (fonttype=42). |
| |
| Used by every fig*.py under code/figures/. Import `apply`, `save`, and the palettes. |
| """ |
| from __future__ import annotations |
|
|
| from pathlib import Path |
|
|
| import matplotlib as mpl |
| import matplotlib.pyplot as plt |
| import seaborn as sns |
|
|
| PALETTE_DEEP = list(sns.color_palette("deep")) |
| PALETTE_MUTED = list(sns.color_palette("muted")) |
| PALETTE_COLORBLIND = list(sns.color_palette("colorblind")) |
|
|
|
|
| def apply() -> None: |
| """Apply the paper figure style. Call once at the top of each fig script.""" |
| sns.set_theme(style="whitegrid", context="paper", font_scale=1.15) |
| mpl.rcParams.update( |
| { |
| "figure.dpi": 150, |
| "savefig.dpi": 300, |
| "savefig.format": "pdf", |
| "savefig.bbox": "tight", |
| |
| "pdf.fonttype": 42, |
| "ps.fonttype": 42, |
| "font.family": "DejaVu Sans", |
| "axes.labelsize": 12, |
| "axes.titlesize": 13, |
| "xtick.labelsize": 10.5, |
| "ytick.labelsize": 10.5, |
| "legend.fontsize": 10, |
| "legend.frameon": False, |
| "axes.grid": True, |
| "grid.alpha": 0.3, |
| "axes.spines.top": False, |
| "axes.spines.right": False, |
| "lines.linewidth": 1.8, |
| "lines.markersize": 5, |
| } |
| ) |
|
|
|
|
| def save(fig, name: str, out_dir) -> None: |
| """Save a figure as both vector PDF and 300-dpi PNG. Closes the figure.""" |
| out_dir = Path(out_dir) |
| out_dir.mkdir(parents=True, exist_ok=True) |
| fig.savefig(out_dir / f"{name}.pdf") |
| fig.savefig(out_dir / f"{name}.png", dpi=300) |
| plt.close(fig) |
|
|