Metadata-Version: 2.4
Name: roycolor
Version: 0.2.0
Summary: Distinctive, accessibility-tested colors and colormaps for scientific figures.
Author: Anirban Roy
License-Expression: MIT
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Scientific/Engineering :: Visualization
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: matplotlib>=3.6
Requires-Dist: numpy>=1.23
Provides-Extra: test
Requires-Dist: pytest>=7; extra == "test"
Dynamic: license-file

# Roycolor

Roycolor is Anirban Roy's distinctive 20-color system for scientific figures.
It provides categorical palettes, perceptually ordered continuous colormaps,
Matplotlib themes, and reproducible accessibility diagnostics.

![Roycolor palette and colormap gallery](roycolor-preview.png)

[View the dark-theme gallery](roycolor-preview-dark.png).

The goal is not merely to make figures colorful. Roycolor uses controlled
lightness, restrained saturation, color-vision-deficiency (CVD) simulations,
and redundant encodings so plots remain legible in journal PDFs, talks, and
grayscale reproduction.

> **Accessibility scope:** no set of colors is universally safe for every
> observer and viewing condition. Roycolor's diagnostic reports are design
> heuristics, not clinical certification. For important categories, combine
> color with markers, line styles, direct labels, or hatching.

## Install for development

```bash
python -m pip install -e ".[test]"
```

## Quick start

```python
import matplotlib.pyplot as plt
import roycolor as roy

roy.set_theme("paper")

fig, ax = plt.subplots()
for index, color in enumerate(roy.palette("signature", 5)):
    ax.plot(x, y[index], color=color, label=f"series {index + 1}")
ax.legend()
```

For dense plots, use the redundant 20-category cycle. Each category receives a
color, marker, and line style:

```python
fig, ax = plt.subplots()
ax.set_prop_cycle(roy.visual_cycle(20))

for index in range(20):
    ax.plot(x, y[index], label=f"series {index + 1}", markevery=8)
```

Importing `roycolor` registers all continuous maps with Matplotlib:

```python
ax.imshow(data, cmap="roycolor_monsoon")
ax.imshow(residuals, cmap="roycolor_balance", vmin=-1, vmax=1)

# Or obtain a configurable colormap object.
ax.imshow(phase, cmap=roy.cmap("orbit", n=512))
```

## Included color systems

Categorical palettes:

- `signature`: the complete twenty-color Roycolor identity
- `core`: the original eight-color identity, in its stable v0.1 order
- `signal`: a compact five-color cycle for small journal figures
- `cool`, `warm`, `earth`, and `pastel`: purpose-specific subsets
- `night`: a higher-lightness cycle for dark backgrounds

Continuous colormaps:

- Sequential: `ember`, `monsoon`, `royal`
- Diverging: `balance`
- Cyclic: `orbit`

Themes:

- `paper`: compact fonts and vector-friendly journal output
- `talk`: larger lines, markers, and type for projection
- `dark`: high-contrast presentation background

Use a theme temporarily when a global style change is undesirable:

```python
with roy.theme_context("paper"):
    fig, ax = plt.subplots()
```

## Preview and audit

```bash
roycolor preview --output roycolor-preview.png
roycolor audit signature
roycolor audit signal --json
```

The audit reports minimum pair separation in OKLab for normal vision and for
full-severity protanopia, deuteranopia, and tritanopia simulations. It reports
grayscale lightness separation separately because color alone should not carry
categorical meaning in a black-and-white figure.

All twenty colors can also be called individually:

```python
roy.colors.DEEP_SEA
roy.colors.MULBERRY
roy.colors.AURORA
roy.colors.MIDNIGHT
roy.colors.ORCHID

# String-based lookup is convenient for configuration files.
roy.colors.get("deep sea")
roy.colors.get("tangerine")
```

## Scientific-use guidance

- Use sequential maps for ordered magnitudes.
- Use `balance` only when the data has a meaningful center such as zero.
- Use `orbit` only for cyclic quantities such as angle or phase.
- Limit categorical figures to twenty categories; do not recycle colors for
  different meanings.
- Prefer `visual_cycle(20)` for more than eight categories, and use
  `hatches(20)` for dense bar charts or filled regions.
- Export journal figures as PDF or SVG where accepted, and inspect the final
  publisher-sized output.

## Method

Roycolor interpolates continuous maps in OKLab rather than directly in sRGB.
Sequential maps enforce increasing perceptual lightness. The categorical colors
were selected for separation under full-severity CVD simulations and retain
deliberately different lightness levels. The included matrices follow Machado,
Oliveira & Fernandes (2009), *A Physiologically-based Model for Simulation of
Color Vision Deficiency*.

## License

MIT
