Metadata-Version: 2.4
Name: matplotlabs
Version: 0.2.0
Summary: Matplotlib styles for science
Project-URL: Homepage, https://github.com/lvvittor/matplotlabs
Project-URL: Repository, https://github.com/lvvittor/matplotlabs
Project-URL: Changelog, https://github.com/lvvittor/matplotlabs/releases
Project-URL: Bug Tracker, https://github.com/lvvittor/matplotlabs/issues
Author-email: Lucas Vittor <lvvittor@gmail.com>
License: MIT License
        
        Copyright (c) 2026 Lucas Vittor
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
License-File: LICENSE
Keywords: matplotlib,plotting,science,styles,visualization
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering
Classifier: Topic :: Scientific/Engineering :: Visualization
Classifier: Typing :: Typed
Requires-Python: >=3.12
Requires-Dist: matplotlib
Provides-Extra: all
Requires-Dist: numpy>=1.16.0; extra == 'all'
Requires-Dist: pytest; extra == 'all'
Requires-Dist: ruff; extra == 'all'
Provides-Extra: dev
Requires-Dist: pytest; extra == 'dev'
Requires-Dist: ruff; extra == 'dev'
Provides-Extra: numpy
Requires-Dist: numpy>=1.16.0; extra == 'numpy'
Description-Content-Type: text/markdown

# matplotlabs

[![PyPI version](https://img.shields.io/pypi/v/matplotlabs)](https://pypi.org/project/matplotlabs/)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
[![CI](https://github.com/lvvittor/matplotlabs/actions/workflows/ci.yml/badge.svg)](https://github.com/lvvittor/matplotlabs/actions/workflows/ci.yml)
[![Python 3.12+](https://img.shields.io/badge/python-3.12%2B-blue)](https://www.python.org/downloads/)

Matplotlib style sheets and colormaps for scientific publications.

`matplotlabs` gives you publication-ready defaults for figures — clean sans-serif
fonts, trimmed spines, constrained layout, and carefully designed color palettes —
so you can focus on the science instead of the formatting.

## Installation

```bash
pip install matplotlabs
```

For development:

```bash
pip install matplotlabs[dev]
```

## Quick start

```python
import matplotlabs as mpll  # registers styles, colormaps, and named colors on import
import matplotlib.pyplot as plt

plt.style.use("mpll")

fig, ax = plt.subplots()
ax.plot([0, 1, 2], [0, 1, 4])
ax.set_xlabel("x")
ax.set_ylabel("y")
fig.savefig("figure.pdf")
```

That's it. The `mpll` style applies publication-ready defaults — sans-serif fonts
(Arial/Helvetica), 3.5 in single-column width, 7 pt font size, no top/right spines,
inward ticks, constrained layout, and PDF output.

## Styles

Styles are composable — stack them in any order with `plt.style.use([...])`.

| Style | Description | Usage |
|---|---|---|
| `mpll` | Default scientific style. Sans-serif (Arial/Helvetica), 3.5 in width, 7 pt fonts, no top/right spines, inward ticks, 8-color qualitative cycle, constrained layout, PDF save. | `plt.style.use("mpll")` |
| `qualitative` | Explicit 8-hue qualitative color cycle at mid-saturation. Same as the default cycle — use when you want to apply the palette without the full base style. | `plt.style.use("qualitative")` |
| `latex` | LaTeX text rendering modifier. Enables `text.usetex` with Helvetica via `helvet` + `sfmath`. Requires a LaTeX installation. | `plt.style.use(["mpll", "latex"])` |

### Composition examples

```python
# Default style with LaTeX rendering
plt.style.use(["mpll", "latex"])

# Just the default style
plt.style.use("mpll")

# Only the color cycle, nothing else
plt.style.use("qualitative")
```

## Named colors

All colors use the `mpll:` prefix (similar to `tab:blue`) and work anywhere
matplotlib accepts a color string. Each hue family has 6 shades numbered
1 (lightest) to 6 (darkest). The unadorned name maps to shade 4.

| Family | `mpll:{name}` (shade 4) | Shades 1-6 |
|---|---|---|
| `lightone` | `#A5A083` | warm cream to dark khaki |
| `grey` | `#6E788D` | light grey to dark slate |
| `red` | `#C5373D` | light pink to dark red |
| `blue` | `#006EAE` | light blue to dark navy |
| `yellow` | `#CA9B23` | light yellow to dark amber |
| `olive` | `#96A00A` | light lime to dark olive |
| `green` | `#429130` | light green to dark green |
| `teal` | `#0096A0` | light teal to dark teal |
| `purple` | `#A1478E` | light lavender to dark purple |
| `orange` | `#E26600` | light peach to dark orange |
| `skin` | `#8D6651` | light beige to dark brown |

### Usage

```python
import matplotlabs as mpll
import matplotlib.pyplot as plt

plt.style.use("mpll")

fig, ax = plt.subplots()
ax.plot([0, 1, 2], [0, 1, 4], color="mpll:red")       # shade 4 (default)
ax.plot([0, 1, 2], [4, 1, 0], color="mpll:blue1")      # lightest blue
ax.axhline(2, color="mpll:grey6")                       # darkest grey
```

### Programmatic access

```python
mpll.colors["red"]        # ['#F6CECA', '#E9A0A5', '#DC6464', '#C5373D', '#9B241C', '#730C0D']
mpll.colors["lightone"]   # ['#F6F2EE', '#E0DCCA', '#C5C1A5', '#A5A083', '#888364', '#5E5948']
```

## Colormaps

All colormaps use the `mpll-` prefix and are registered automatically on import.
Each colormap also has a reversed variant with the `_r` suffix.

### Sequential

| Colormap | Colors |
|---|---|
| `mpll-red` | light pink to dark red |
| `mpll-blue` | light blue to dark navy |
| `mpll-teal` | light teal to dark teal |
| `mpll-green` | light green to dark green |
| `mpll-yellow` | light yellow to dark amber |
| `mpll-orange` | light peach to dark orange |
| `mpll-purple` | light lavender to dark purple |
| `mpll-grey` | light grey to dark slate |
| `mpll-olive` | light lime to dark olive |
| `mpll-lightone` | warm cream to dark khaki |
| `mpll-skin` | light beige to dark brown |

### Diverging

| Colormap | Description |
|---|---|
| `mpll-red-blue` | Red ← white → blue |
| `mpll-orange-teal` | Orange ← white → teal |
| `mpll-purple-green` | Purple ← white → green |

### Usage

```python
import matplotlabs as mpll
import matplotlib.pyplot as plt
import numpy as np

data = np.random.randn(10, 10)

fig, ax = plt.subplots()
im = ax.imshow(data, cmap="mpll-red-blue")
fig.colorbar(im, ax=ax)

# Reversed variant
im2 = ax.imshow(data, cmap="mpll-red-blue_r")
```

## Utilities

### `annotate_heatmap`

Overlay formatted numbers on each cell of a heatmap with automatic text color
contrast (dark text on light cells, light text on dark cells).

```python
import matplotlabs as mpll
import matplotlib.pyplot as plt
import numpy as np

plt.style.use("mpll")

data = np.array([[1.0, -0.5, 0.3], [-0.8, 0.001, 2500]])

fig, ax = plt.subplots()
im = ax.imshow(data, cmap="mpll-red-blue")
mpll.annotate_heatmap(im, data)
fig.colorbar(im, ax=ax)
fig.savefig("heatmap.pdf")
```

Parameters:

- **`im`** — The `AxesImage` returned by `ax.imshow()`.
- **`data`** — The 2-D numpy array used to create the image.
- **`fmt`** — Explicit format string (e.g. `"{:.2f}"`). When `None`, each cell auto-selects between fixed-point, scientific notation, or integer formatting.
- **`sci_threshold`** — Magnitude threshold for scientific notation (default `1e3`).
- **`fontsize`** — Annotation font size. Defaults to `rcParams["font.size"] - 1`.
- **`textcolors`** — Tuple of `(low_color, high_color)` for contrast. Default `("black", "white")`.
- **`threshold`** — Colormap midpoint for switching text color. Defaults to `(vmin + vmax) / 2`.

## Default style (`mpll`)

The `mpll` style sets these key rcParams:

| Parameter | Value |
|---|---|
| Font family | Sans-serif (Arial, Helvetica) |
| Font size | 7 pt |
| Figure size | 3.5 x 2.5 in |
| Figure DPI | 450 |
| Save DPI | 300 |
| Save format | PDF |
| Spines | Bottom + left only |
| Ticks | Major only, inward, no minor |
| Layout | Constrained layout |
| Legend | No frame, 6 pt |
| Grid | Off |
| Marker size | 3 |
| Color cycle | 8 hues at mid-saturation |

## Development

```bash
# Clone and install in editable mode
git clone https://github.com/lvvittor/matplotlabs.git
cd matplotlabs
pip install -e ".[dev]"

# Run tests
pytest

# Lint and format
ruff check .
ruff format .

# Generate example figures
python examples/plot.py
```

## License

[MIT](LICENSE)
