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 points

  • FONT_SIZE (int, required): Body text font size in points

  • LATEX_PREAMBLE (str, optional): LaTeX packages for math rendering

  • TEXTHEIGHT_PT (float, optional): Document textheight in points

Class Methods

  • set_mpl(use_latex=None): Apply style to matplotlib globally

  • fig(width=1.0, aspect=None, **kwargs): Create single-panel figure

  • fig_grid(nrows=1, ncols=2, width=1.0, aspect=None, **kwargs): Create multi-panel figure

  • fig_size(width=1.0, aspect=None): Get figure dimensions in inches

  • textwidth(): Get textwidth in inches

  • textheight(): 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.colors palette

Tips and Best Practices

Measuring Textwidth

  1. Create a minimal LaTeX document with your journal’s document class

  2. Add \the\textwidth in the document body

  3. Compile 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)