Skip to content

nicefigs

nicefigs

Publication-grade, modular matplotlib plotting for geoscience.

nicefigs is a thin, composable layer on top of matplotlib. It gives you a single consistent house style (sans-serif, journal-like), physical figure sizing that keeps fonts consistent across every panel, and a toolbox of geoscience-ready plots: global/regional maps, ternary maps & scatters, image grids, tight colorbars, KDE agreement plots, model-comparison violins, timeseries, and map animations.

Composite figure

Design philosophy

One consistent house style. A small, explicit Theme dataclass bundles font sizes, line widths, and colours. Call nicefigs.set_theme("paper") once and every helper — maps, scatter plots, heatmaps, timeseries — renders with matching fonts, tick sizes, and spine weights.

Physical figure sizing. You almost never want to think in inches. You want "a single-column figure" or "half the text width". Because font sizes live in points and figure sizes live in inches, nicefigs.figure / nicefigs.subplots solve the figure size from a named physical target (width="single", width="half", ...) and an aspect ratio. The rendered figure lands at exactly the requested physical size, with fonts at exactly the theme's point sizes — so a multi-panel paper figure looks consistent whether one panel is a map and another is a scatter plot.

Modular, composable helpers. Every plotting function accepts an existing ax (or fig) where it makes sense, so you can drop nicefigs pieces into your own matplotlib layouts — a GridSpec, a plt.subplots grid, an inset axes — rather than being handed a fixed figure you have to fight with. The composite figure example shows a map, a timeseries, and an agreement plot composed into one GridSpec, all sharing one theme and one physical width.

Install

pip install nicefigs

# with cartopy-backed map projections
pip install "nicefigs[maps]"

# with xarray input helpers
pip install "nicefigs[xarray]"

# both
pip install "nicefigs[all]"

A first example

The figure above is built from three independently composable pieces — a map, a timeseries, and an agreement plot — arranged in a GridSpec, all at one consistent physical width. See it fully worked through in the Gallery and Quickstart.

import nicefigs as nf
from nicefigs import data

nf.set_theme("paper")

lon, lat, temp = data.global_points(field="temperature")
fig, ax, m = nf.map(
    lon, lat, temp,
    cmap="RdYlBu_r",
    colorbar_label="air temperature [°C]",
    title="Mean annual air temperature",
)
nf.save(fig, "figures/global_map", formats=("pdf", "png"))

Global map

Continue to the Quickstart or browse the full Gallery for every plot family, or jump straight to the API Reference.