"""Journal-style figure settings (serif text, Times-like math, thin spines, grayscale-safe palette, panel labels).""" import matplotlib matplotlib.use("Agg") import matplotlib.pyplot as plt from matplotlib import rcParams PALETTE = {"cpu1": "#8c8c8c", "cpuN": "#1a1a1a", "metal": "#b2182b", "metal_unfused": "#ef8a62", "pandas": "#999999", "polars": "#4393c3", "duckdb": "#2166ac", "raid": "#b2182b", "neutral": "#4d4d4d"} MARK = {"cpu1": "s", "cpuN": "o", "metal": "^", "metal_unfused": "v"} LABEL = {"cpu1": "CPU, 1 thread", "cpuN": "CPU, 18 threads", "metal": "Metal (fused)", "metal_unfused": "Metal (4 kernels)"} def setup(): rcParams.update({ "font.family": "serif", "font.serif": ["STIX Two Text", "Times New Roman", "Times", "DejaVu Serif"], "mathtext.fontset": "stix", "font.size": 8.5, "axes.titlesize": 9, "axes.labelsize": 8.5, "legend.fontsize": 7.5, "xtick.labelsize": 7.5, "ytick.labelsize": 7.5, "axes.linewidth": 0.6, "xtick.major.width": 0.5, "ytick.major.width": 0.5, "xtick.major.size": 2.5, "ytick.major.size": 2.5, "xtick.direction": "out", "ytick.direction": "out", "axes.spines.top": False, "axes.spines.right": False, "legend.frameon": False, "legend.handlelength": 1.8, "lines.linewidth": 1.0, "lines.markersize": 3.5, "figure.dpi": 200, "savefig.dpi": 300, "pdf.fonttype": 42, "axes.grid": False, "axes.prop_cycle": matplotlib.cycler(color=["#1a1a1a", "#b2182b", "#2166ac", "#4d4d4d", "#ef8a62"]), }) def panel(ax, letter, title=None): """Panel label in the Journal-of-Finance style: 'Panel A. Title' above the axes, left-aligned.""" t = f"Panel {letter}." + (f" {title}" if title else "") ax.set_title(t, loc="left", fontsize=8.5, fontweight="bold", pad=6) def light_grid(ax, axis="y"): ax.grid(True, axis=axis, color="#d9d9d9", linewidth=0.4, linestyle="-", zorder=0); ax.set_axisbelow(True) def ref_line(ax, y=1.0, label=None): ax.axhline(y, color="#4d4d4d", linewidth=0.6, linestyle=(0, (4, 2)), zorder=1) if label: ax.annotate(label, xy=(1.0, y), xycoords=("axes fraction", "data"), xytext=(-2, 2), textcoords="offset points", ha="right", va="bottom", fontsize=7, color="#4d4d4d") def fmt_elements(ax): ax.set_xscale("log"); ax.set_xlabel("Elements (returns)")