Paper Styles System
The cosmic_toolbox.styles module provides a flexible system for creating publication-ready matplotlib figures that match specific journal formatting requirements.
Overview
The paper styles system automatically configures matplotlib to produce figures with the correct dimensions, fonts, and styling for various academic journals. It handles:
Figure sizing based on journal textwidth
Font configuration with LaTeX rendering
Consistent styling (line widths, tick directions, etc.)
Easy creation of single and multi-panel figures
Available Styles
Currently available:
JCAP - Journal of Cosmology and Astroparticle Physics
Using an Existing Style
Using JCAP as an Example
Import and apply the style:
from cosmic_toolbox.styles import jcap
import matplotlib.pyplot as plt
# Apply the JCAP style globally
jcap.set_mpl()
# Create a figure (full textwidth with golden ratio aspect)
fig, ax = jcap.fig()
ax.plot([1, 2, 3], [1, 4, 9])
plt.savefig("figure.pdf")
Creating Figures
Single-panel figure with flexible sizing:
# Full textwidth (default)
fig, ax = jcap.fig()
# Half-width
fig, ax = jcap.fig(width=0.5)
# Custom aspect ratio (aspect = height/width)
fig, ax = jcap.fig(width=1.0, aspect=0.8)
# Absolute width
fig, ax = jcap.fig(width="3.5in")
Multi-panel figure:
# 1 row, 2 columns
fig, axes = jcap.fig_grid(nrows=1, ncols=2)
# Custom grid
fig, axes = jcap.fig_grid(nrows=2, ncols=3, width=1.0, aspect=1.2)
Utilities
Get figure dimensions:
width_in, height_in = jcap.fig_size(width=0.5, aspect=0.618)
Get textwidth in inches:
full_width = jcap.textwidth()
LaTeX Rendering
By default, LaTeX rendering is auto-detected. Control it explicitly:
# Force LaTeX (requires LaTeX installation)
jcap.set_mpl(use_latex=True)
# Use mathtext fallback
jcap.set_mpl(use_latex=False)
Creating a New Style
To add support for a new journal, create a new style class that inherits from PaperStyle.
Step 1: Measure Your Document Parameters
Add the following to your LaTeX document to measure the textwidth:
\documentclass[...]{article}
\usepackage{yourjournal}
\begin{document}
Textwidth: \the\textwidth
\end{document}
Compile the document to get the textwidth in points (e.g., 440.0pt).
Step 2: Create Your Style Class
Create a new file src/cosmic_toolbox/styles/yourjournal.py:
from .base import PaperStyle
class YourJournal(PaperStyle):
"""
Style for Your Journal Name.
Document setup:
\\documentclass[options]{article}
\\usepackage{yourjournal}
Textwidth measured with \\the\\textwidth → XXX.X pt
"""
# Required: textwidth in points
TEXTWIDTH_PT = 440.0 # Replace with your measurement
# Required: body text font size
FONT_SIZE = 11
# Optional: LaTeX packages for math rendering
LATEX_PREAMBLE = (
r"\usepackage{amsmath}"
r"\usepackage{amssymb}"
r"\usepackage{bm}"
)
# Optional: textheight for full-page figures
# TEXTHEIGHT_PT = 650.0
# Module-level API (enables yourjournal.fig() syntax)
set_mpl = YourJournal.set_mpl
fig = YourJournal.fig
fig_grid = YourJournal.fig_grid
fig_size = YourJournal.fig_size
textwidth = YourJournal.textwidth
Step 3: Use Your New Style
from cosmic_toolbox.styles import yourjournal
yourjournal.set_mpl()
fig, ax = yourjournal.fig()
Complete Example: Creating an A&A Style
Let’s create a style for Astronomy & Astrophysics:
# src/cosmic_toolbox/styles/aa.py
from .base import PaperStyle
class AA(PaperStyle):
"""
Astronomy & Astrophysics style.
Document setup:
\\documentclass{aa}
Textwidth: \\the\\textwidth → 523.5 pt
"""
TEXTWIDTH_PT = 523.5 # Two-column: 240.0 pt for single column
FONT_SIZE = 10
LATEX_PREAMBLE = (
r"\usepackage{amsmath}"
r"\usepackage{amssymb}"
)
# Module-level API
set_mpl = AA.set_mpl
fig = AA.fig
fig_grid = AA.fig_grid
fig_size = AA.fig_size
textwidth = AA.textwidth
Then use it:
from cosmic_toolbox.styles import aa
# Apply style
aa.set_mpl()
# Single-column figure (50% of full textwidth)
fig, ax = aa.fig(width=0.5)
# Two-column figure (full textwidth)
fig, ax = aa.fig(width=1.0)
Advanced: Overriding Default Behavior
The PaperStyle base class provides sensible defaults. Override methods for custom behavior:
class CustomJournal(PaperStyle):
TEXTWIDTH_PT = 500.0
FONT_SIZE = 12
@classmethod
def set_mpl(cls, use_latex=None):
# Call parent implementation
super().set_mpl(use_latex)
# Add custom rcParams
import matplotlib as mpl
mpl.rcParams.update({
'axes.grid': True, # Enable grid by default
'grid.alpha': 0.3,
})
PaperStyle Base Class Reference
Class Attributes to Override
TEXTWIDTH_PT(float, required): Document textwidth in pointsFONT_SIZE(int, required): Body text font size in pointsLATEX_PREAMBLE(str, optional): LaTeX packages for math renderingTEXTHEIGHT_PT(float, optional): Document textheight in points
Class Methods
set_mpl(use_latex=None): Apply style to matplotlib globallyfig(width=1.0, aspect=None, **kwargs): Create single-panel figurefig_grid(nrows=1, ncols=2, width=1.0, aspect=None, **kwargs): Create multi-panel figurefig_size(width=1.0, aspect=None): Get figure dimensions in inchestextwidth(): Get textwidth in inchestextheight(): Get textheight in inches (if set)
Constants
PT_PER_INCH = 72.27: Conversion factor (LaTeX points to inches)GOLDEN = (1 + √5)/2 ≈ 1.618: Golden ratio for default aspect
Style Configuration
What set_mpl() Configures
The base PaperStyle.set_mpl() method automatically configures:
- Figure:
Default figure size based on textwidth
Display DPI: 150, Save DPI: 600
PDF output format with tight bounding box
Constrained layout enabled
- Fonts:
LaTeX rendering (auto-detected or specified)
Serif font family
Sizes: body, axes labels, tick labels, legend
- Axes:
Label sizes and padding
Line widths
MathText formatting for scientific notation
- Ticks:
Inward-pointing on all sides
Minor ticks visible
Appropriate sizes and widths
- Legend:
Frameless, compact spacing
Appropriate font size
- Lines & Markers:
Publication-quality line widths
Antialiasing enabled
- Colors:
Uses
cosmic_toolbox.colorspalette
Tips and Best Practices
Measuring Textwidth
Create a minimal LaTeX document with your journal’s document class
Add
\the\textwidthin the document bodyCompile and note the value in points
For Two-Column Layouts
Measure both the full textwidth and single-column width:
Single column: \the\columnwidth → 240.0 pt
Full width: \the\textwidth → 523.5 pt
Then create figures with appropriate widths:
# Single column
fig, ax = journal.fig(width=240.0/523.5) # ≈ 0.46
# Full width
fig, ax = journal.fig(width=1.0)
Golden Ratio
The default aspect ratio of 1/φ ≈ 0.618 provides aesthetically pleasing proportions. Override when needed:
# Square figure
fig, ax = journal.fig(aspect=1.0)
# 16:9 figure
fig, ax = journal.fig(aspect=9/16)