Skip to main content

Small vector-first scientific plotting with clean publication-style defaults.

Project description

cleanfig

cleanfig is a small Rust/Python plotting package for clean scientific figures with vector-first export.

It is intentionally narrow: simple publication-style defaults, light visual clutter, compact labeling, and a small public API. The focus is on figures that should look close to final output without extensive styling code.

Cleanfig example showing a four-panel scientific figure

Installation

Install the latest GitHub version:

pip install git+https://github.com/adakite/cleanfig.git

Planned future PyPI install:

pip install cleanfig

Quick Start

import numpy as np
import cleanfig as cf

x = np.linspace(0, 10, 200)
y = np.sin(x)

fig = cf.figure(width="single", height=3.4, panel_labels=False)
ax = fig.panel(0, 0)
ax.line(x, y, label="signal")
ax.scatter(x[::20], y[::20], size=5)
ax.xlabel("x")
ax.ylabel("y")

fig.save("basic_line.svg")
fig.save("basic_line.html")
fig.save("basic_line.pdf")

Public API

The package is designed to be used as:

import cleanfig as cf

Current public entry points:

  • cf.figure(...)
  • Figure.panel(row, col)
  • Figure.save(path)
  • Panel.scatter(...)
  • Panel.line(...)
  • Panel.bar(...)
  • Panel.histogram(...)
  • Panel.field(...)
  • Panel.violin(...)
  • Panel.box(...)
  • Panel.colorbar(...)
  • Panel.legend()
  • Panel.xlabel(...)
  • Panel.ylabel(...)
  • Panel.right_ylabel(...)
  • Panel.xscale(...)
  • Panel.yscale(...)
  • Panel.limits(...)
  • Panel.right_limits(...)

API Reference

cf.figure(width="single", height=4.0, grid=(1, 1), panel_labels=False, font=None, theme="publication")

  • width: "single" or "double"
  • height: figure height in inches
  • grid: (rows, cols)
  • panel_labels: add panel letters
  • font: custom font family string
  • theme: "publication" / "nature" / "light" alias, or "dark"

Axis labels, limits, and scales

  • ax.xlabel(label)
  • ax.ylabel(label)
  • ax.right_ylabel(label): label for a secondary right Y axis
  • ax.limits(x=None, y=None): explicit limits for the main X/Y axes
  • ax.right_limits(y=None): explicit limits for the right Y axis
  • ax.xscale("linear" | "log")
  • ax.yscale("linear" | "log", axis="left" | "right")

Log scales require strictly positive values and strictly positive limits.

ax.scatter(x, y, color=None, size=6.0, alpha=0.8, label=None, cmap=None, yaxis="left")

  • x, y: same-length numeric arrays
  • color: named/hex color or numeric array for colormap mapping
  • size: marker diameter in points
  • alpha: opacity
  • label: legend entry
  • cmap: colormap name for mapped colors
  • yaxis: "left" or "right" for dual-Y figures

Returns a PlotHandle when color mapping is used.

ax.line(x, y, color=None, width=1.2, alpha=1.0, label=None, yaxis="left")

  • color: named/hex color
  • width: stroke width in points
  • alpha: opacity
  • label: legend entry
  • yaxis: "left" or "right"

ax.bar(labels, values, yaxis="left", color=None, alpha=1.0)

  • labels: categorical X labels
  • values: numeric heights
  • yaxis: "left" or "right"
  • color: named/hex color
  • alpha: opacity

ax.histogram(data, bins=12, range=None, density=False, color=None, alpha=1.0, label=None, yaxis="left")

  • data: numeric samples
  • bins: number of bins
  • range: optional (min, max) binning range
  • density: normalize to probability density instead of counts
  • color: named/hex fill color
  • alpha: opacity
  • label: legend entry
  • yaxis: "left" or "right"

ax.field(grid, cmap=None, cell_edges=False)

  • grid: 2D numeric array
  • cmap: colormap name
  • cell_edges: draw subtle cell borders when True

Returns a PlotHandle for optional colorbar creation.

ax.colorbar(handle, label=None, placement=None, style=None)

  • handle: result of a mapped scatter, field, or mapped-point violin
  • label: colorbar label
  • placement: "right" or "inside-left"
  • style: "binned" or "continuous"

Current default is "binned".

ax.violin(data, labels=None, show_median=False, points=False, point_color=None, point_size=4.0, point_alpha=0.75, point_cmap=None)

  • data: grouped numeric data
  • labels: category labels
  • show_median: draw median segment
  • points: overlay individual points
  • point_color: constant color, flat array, or grouped arrays
  • point_size: point diameter
  • point_alpha: point opacity
  • point_cmap: colormap for mapped points

Returns a PlotHandle when mapped point colors are used.

ax.box(data, labels=None)

  • data: grouped numeric data
  • labels: category labels

ax.legend()

Creates a compact frameless legend from labeled layers.

Current Feature Status

  • Supported: line, scatter, bar, histogram, violin, box, small vector field plots
  • Supported: light/dark themes, log X/Y axes, dual Y axes, SVG/HTML/PDF export
  • Not supported yet: ax.spectrogram(), logarithmic colorbars, raster rendering, geographic projections

Examples

Useful example scripts are provided in examples/:

  • basic_line.py
  • four_panels.py
  • violin_box.py
  • esec_dual_y_light.py for a light-theme dual-Y example using a pandas.DataFrame loaded from a bundled ESEC catalog extract in examples/Data/
  • theme-specific wrappers for light/dark example output

Export Formats

Supported export targets:

  • SVG
  • HTML with embedded SVG
  • PDF through SVG conversion in the Rust backend

Design Philosophy

  • vector-first output
  • clean left/bottom axes by default
  • minimal plot constructors
  • no GUI, dashboards, or heavyweight plotting state
  • useful scientific defaults over maximum flexibility

Fallback Behavior

cleanfig prefers the compiled Rust extension.

If the extension is unavailable, it falls back to a pure Python implementation. The fallback is intended for graceful local use and testing, but it is not feature-complete. In particular, PDF export is only available when the Rust backend is loaded.

You can inspect the active backend with:

import cleanfig as cf
print(cf.BACKEND)

Current Limitations

  • no ax.spectrogram() yet
  • no logarithmic colorbars
  • no raster backend
  • no geographic projections
  • visual styling is intentionally constrained
  • field rendering is intended for small grids only

Development Install

python -m venv .venv
source .venv/bin/activate
python -m pip install -U pip
python -m pip install -e ".[dev]"
maturin develop
pytest -q

The esec_dual_y_light.py example additionally expects pandas, which is included in the dev extra. The bundled ESEC source file and citation notes are stored under examples/Data/.

Citation, License, Contact

  • License: MIT, see LICENSE
  • Changelog: CHANGELOG.md
  • Release checklist: RELEASE.md
  • Contact: Antoine Lucas

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cleanfig-1.0.0.tar.gz (157.9 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

cleanfig-1.0.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.2 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ x86-64

cleanfig-1.0.0-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl (4.0 MB view details)

Uploaded CPython 3.10+macOS 10.12+ universal2 (ARM64, x86-64)macOS 10.12+ x86-64macOS 11.0+ ARM64

File details

Details for the file cleanfig-1.0.0.tar.gz.

File metadata

  • Download URL: cleanfig-1.0.0.tar.gz
  • Upload date:
  • Size: 157.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for cleanfig-1.0.0.tar.gz
Algorithm Hash digest
SHA256 bce9cd52ae9f6561afdf5c307f8b4242d3a14114e1109a3663c36cd361a3b51b
MD5 4f2d6f7b6b98668df912713f159f7e7a
BLAKE2b-256 d93f3c9fb761001fb9fcacae521eed2ae50ca12d780efdbfca7e62c87b6aa3b1

See more details on using hashes here.

Provenance

The following attestation bundles were made for cleanfig-1.0.0.tar.gz:

Publisher: release.yml on adakite/cleanfig

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file cleanfig-1.0.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for cleanfig-1.0.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 42f3e380a68d594da69e631365c77aaccb4f19ae19df2a40d93fa6e247762cb4
MD5 24a960cd3064bf6eff1450fb127690a2
BLAKE2b-256 47fb5f2b4126171304906ee139ee120e7b14138500d88cdaea3dc87fb28f9f33

See more details on using hashes here.

Provenance

The following attestation bundles were made for cleanfig-1.0.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on adakite/cleanfig

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file cleanfig-1.0.0-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl.

File metadata

File hashes

Hashes for cleanfig-1.0.0-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Algorithm Hash digest
SHA256 b6d32a382ce2c0f0af69aa3f14af1869b04f26c62a18eafe62a59a950b26be3d
MD5 e3aaaf48c01bbe6368d1079ef1b12498
BLAKE2b-256 a7f90d9c9b22e24a43b9b84981a6c7a617a944c209f759a38753564d02cd5e66

See more details on using hashes here.

Provenance

The following attestation bundles were made for cleanfig-1.0.0-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl:

Publisher: release.yml on adakite/cleanfig

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page