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.
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 inchesgrid:(rows, cols)panel_labels: add panel lettersfont: custom font family stringtheme:"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 axisax.limits(x=None, y=None): explicit limits for the main X/Y axesax.right_limits(y=None): explicit limits for the right Y axisax.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 arrayscolor: named/hex color or numeric array for colormap mappingsize: marker diameter in pointsalpha: opacitylabel: legend entrycmap: colormap name for mapped colorsyaxis:"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 colorwidth: stroke width in pointsalpha: opacitylabel: legend entryyaxis:"left"or"right"
ax.bar(labels, values, yaxis="left", color=None, alpha=1.0)
labels: categorical X labelsvalues: numeric heightsyaxis:"left"or"right"color: named/hex coloralpha: opacity
ax.histogram(data, bins=12, range=None, density=False, color=None, alpha=1.0, label=None, yaxis="left")
data: numeric samplesbins: number of binsrange: optional(min, max)binning rangedensity: normalize to probability density instead of countscolor: named/hex fill coloralpha: opacitylabel: legend entryyaxis:"left"or"right"
ax.field(grid, cmap=None, cell_edges=False)
grid: 2D numeric arraycmap: colormap namecell_edges: draw subtle cell borders whenTrue
Returns a PlotHandle for optional colorbar creation.
ax.colorbar(handle, label=None, placement=None, style=None)
handle: result of a mappedscatter,field, or mapped-pointviolinlabel: colorbar labelplacement:"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 datalabels: category labelsshow_median: draw median segmentpoints: overlay individual pointspoint_color: constant color, flat array, or grouped arrayspoint_size: point diameterpoint_alpha: point opacitypoint_cmap: colormap for mapped points
Returns a PlotHandle when mapped point colors are used.
ax.box(data, labels=None)
data: grouped numeric datalabels: 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.pyfour_panels.pyviolin_box.pyesec_dual_y_light.pyfor a light-theme dual-Y example using apandas.DataFrameloaded from a bundled ESEC catalog extract inexamples/Data/- theme-specific wrappers for light/dark example output
Export Formats
Supported export targets:
SVGHTMLwith embedded SVGPDFthrough 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
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cleanfig-0.1.0.tar.gz.
File metadata
- Download URL: cleanfig-0.1.0.tar.gz
- Upload date:
- Size: 78.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a438202e17f91fe5b048fd1d39c29e19d75130caa52a2cc8b315b6d1ffef3d21
|
|
| MD5 |
b431e27dbf4cca64d4901d7b357b843a
|
|
| BLAKE2b-256 |
b77d7b0015b84c50cfd3bd9254aaf81be2096b7f187b6164defe7f5146594f60
|
Provenance
The following attestation bundles were made for cleanfig-0.1.0.tar.gz:
Publisher:
release.yml on adakite/cleanfig
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cleanfig-0.1.0.tar.gz -
Subject digest:
a438202e17f91fe5b048fd1d39c29e19d75130caa52a2cc8b315b6d1ffef3d21 - Sigstore transparency entry: 2033631448
- Sigstore integration time:
-
Permalink:
adakite/cleanfig@e8550eeb6d8cbb2e1aad5f9b224977f06096a34d -
Branch / Tag:
refs/heads/main - Owner: https://github.com/adakite
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@e8550eeb6d8cbb2e1aad5f9b224977f06096a34d -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file cleanfig-0.1.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: cleanfig-0.1.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 2.2 MB
- Tags: CPython 3.10+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5f676b6516afeb3b0adda0479f00be25859a2feb9c1e6fcb587a9cea1c595a68
|
|
| MD5 |
79700bc4532f6db2401fc73e3858a5ac
|
|
| BLAKE2b-256 |
e3d36b3be476026fda8f8451153680768993b605bf64c042bb34e40a8bb8a108
|
Provenance
The following attestation bundles were made for cleanfig-0.1.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
release.yml on adakite/cleanfig
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cleanfig-0.1.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
5f676b6516afeb3b0adda0479f00be25859a2feb9c1e6fcb587a9cea1c595a68 - Sigstore transparency entry: 2033631616
- Sigstore integration time:
-
Permalink:
adakite/cleanfig@e8550eeb6d8cbb2e1aad5f9b224977f06096a34d -
Branch / Tag:
refs/heads/main - Owner: https://github.com/adakite
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@e8550eeb6d8cbb2e1aad5f9b224977f06096a34d -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file cleanfig-0.1.0-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl.
File metadata
- Download URL: cleanfig-0.1.0-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
- Upload date:
- Size: 4.0 MB
- Tags: CPython 3.10+, macOS 10.12+ universal2 (ARM64, x86-64), macOS 10.12+ x86-64, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b789158fa5aa1ff59ce4008f5a24f3b2954212489f6d2f4a146ca52f79bc7768
|
|
| MD5 |
ca894314f20c96baecaaca95db66475a
|
|
| BLAKE2b-256 |
e1e358e0e6fcc1eb0b8f5a0beb2033d2c3270924cd48741436cfcbd53032918a
|
Provenance
The following attestation bundles were made for cleanfig-0.1.0-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl:
Publisher:
release.yml on adakite/cleanfig
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cleanfig-0.1.0-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl -
Subject digest:
b789158fa5aa1ff59ce4008f5a24f3b2954212489f6d2f4a146ca52f79bc7768 - Sigstore transparency entry: 2033631528
- Sigstore integration time:
-
Permalink:
adakite/cleanfig@e8550eeb6d8cbb2e1aad5f9b224977f06096a34d -
Branch / Tag:
refs/heads/main - Owner: https://github.com/adakite
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@e8550eeb6d8cbb2e1aad5f9b224977f06096a34d -
Trigger Event:
workflow_dispatch
-
Statement type: