Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
prismatica
The universal compile-time scientific colormap library for Rust
[!IMPORTANT] Pre-1.0.0 — the API may change between minor versions. The API will be considered stable at 1.0.0.
Status
| Component | Status | Count |
|---|---|---|
Core types (Color, Colormap, ColormapMeta, DiscretePalette) |
Done | |
| Registry (discovery, filtering, palette lookup) | Done | |
| Prelude module | Done | |
| matplotlib | Done | 8 maps |
| Crameri | Done | 40 maps |
| CET | Done | 59 maps |
| CMOcean | Done | 22 maps |
| Moreland | Done | 6 maps |
| CMasher | Done | 53 maps |
| ColorBrewer | Done | 35 maps + 35 palettes |
| CartoColors | Done | 34 maps + 34 palettes |
| NCAR NCL | Done | 44 maps |
| d3 | Done | 7 maps + 1 palette |
| Framework integrations (19 crates) | Done | |
| Total | 308 colormaps + 70 palettes |
Highlights
- 308 scientific colormaps from 10 established collections
- 70 discrete palettes for categorical data (ColorBrewer, CartoColors, d3)
- Compile-time constants -- zero runtime file I/O, zero parsing
#![no_std]-- core functionality works without allocation- Continuous sampling -- linear interpolation between 256-step LUT entries for any
tin[0, 1] - Rich metadata -- every colormap carries its kind, perceptual uniformity flag, CVD safety, and citation
- Feature-gated collections -- include only the maps you need; ~1 KB per colormap
- Framework integrations -- bidirectional conversion for 19 crates including plotters, egui, image, bevy, ratatui, iced, palette, and more
- Sibling project -- chromata provides editor color themes with the same Color type and integration pattern
For Everyone
What are scientific colormaps?
A colormap is a function that converts a scalar value (like temperature, elevation, or density) into a color. When you see a weather map where blue means cold and red means hot, that is a colormap at work.
Perceptual uniformity means that equal steps in data produce equal steps in perceived color difference. Without it, your visualization can create false features -- bright bands or phantom boundaries that exist in the colormap but not in the data. The classic "rainbow" and "jet" colormaps are notorious for this.
Prismatica provides every established scientific colormap collection as compile-time Rust data. A researcher writes BATLOW.eval(0.5) and gets a perceptually uniform, colorblind-safe color. No files to load, no dependencies to install.
Quick start
Add prismatica to your project:
[]
= "0.3.0"
Use a colormap:
use BATLOW;
let color = BATLOW.eval;
println!;
Supported collections
| Collection | Author / Organization | Maps | Palettes | Type |
|---|---|---|---|---|
| Matplotlib | van der Walt, Smith, Firing | 8 | Sequential, perceptually uniform | |
| Crameri | Fabio Crameri | 40 | Sequential, diverging, multi-sequential, cyclic | |
| CET | Peter Kovesi | 59 | Sequential, diverging, cyclic, rainbow, isoluminant | |
| CMOcean | Kristen Thyng | 22 | Oceanographic sequential, diverging | |
| ColorBrewer | Cynthia Brewer | 35 | 35 | Sequential, diverging, qualitative |
| CMasher | Ellert van der Velden | 53 | Sequential, diverging (astrophysics) | |
| NCAR NCL | NCAR | 44 | Geoscience sequential, diverging | |
| CartoColors | CARTO | 34 | 34 | Cartographic sequential, diverging, qualitative |
| Moreland | Kenneth Moreland | 6 | Cool-warm diverging, black body, Kindlmann | |
| d3 | Mike Bostock | 7 | 1 | Turbo, Rainbow, Sinebow, Cubehelix, Tableau10 |
| Total | 308 | 70 |
Choosing the right colormap
| Data type | Recommended maps | Why |
|---|---|---|
| Sequential (temperature, elevation) | batlow, viridis, oslo, thermal |
Monotonic luminance, perceptually uniform |
| Diverging (anomalies, residuals) | berlin, vik, balance, smooth-cool-warm |
Neutral center, symmetric extremes |
| Cyclic (phase, direction, time-of-day) | romaO, phase, twilight |
End color equals start color |
| Categorical (labels, classes) | SET2, DARK2, PAIRED, Tableau10 |
Maximally distinct, non-interpolated |
What prismatica is not
- Not a color manipulation library (use
palettefor that) - Not a gradient builder (use
colorgradfor custom gradients) - Not a rendering engine
- Not a data visualization framework
Prismatica is the data layer. It answers one question: given a colormap name and a scalar t in [0, 1], what RGB color should I use?
For Researchers
The Color type
Methods: new(r, g, b), from_hex(0xFF8800), to_css_hex(), to_f32(), lerp(other, t), luminance(), contrast_ratio(other).
Colormap sampling
use BATLOW;
// Continuous: sample at any float in [0, 1]
let color = BATLOW.eval;
// Rational: the 30th of 100 evenly-spaced samples
let color = BATLOW.eval_rational;
// Reversed direction (zero allocation)
let rev = BATLOW.reversed;
let color = rev.eval; // equivalent to BATLOW.eval(0.8)
// Extract N discrete colors
let legend_colors = BATLOW.colors;
Values outside [0, 1] are clamped. Interpolation is linear in sRGB space, matching matplotlib, ParaView, and most scientific tools.
Colormap discovery
use ;
// Find all perceptually uniform diverging colormaps
let diverging: = all_colormaps
.iter
.filter
.collect;
// Look up by name
let viridis = find_by_name.unwrap;
// Filter by collection
let crameri_maps = filter_by_collection;
Discrete palettes
ColorBrewer, CartoColors, and d3 provide discrete palettes alongside continuous colormaps:
use SET2_PALETTE;
for i in 0..SET2_PALETTE.len
// Also available via the registry
let palette = find_palette_by_name.unwrap;
Feature flags
| Feature | Maps | Description |
|---|---|---|
core (default) |
48 | matplotlib + Crameri -- the maps journals recommend |
matplotlib |
8 | viridis, inferno, magma, plasma, cividis, twilight, mako, rocket |
crameri |
40 | batlow, berlin, roma, oslo, tokyo, hawaii, and more |
cet |
59 | CET-L*, CET-D*, CET-C*, CET-R* perceptually uniform maps |
cmocean |
22 | thermal, haline, solar, ice, deep, and 17 more |
colorbrewer |
35 + 35 palettes | Blues, RdBu, Set2, Spectral, and more |
cmasher |
53 | ember, ocean, gothic, fusion, wildfire, and more |
ncar |
44 | NCAR NCL geoscience colour tables |
cartocolors |
34 + 34 palettes | CARTO cartographic colour schemes |
moreland |
6 | cool-warm, black body, Kindlmann, extended variants |
d3 |
7 + 1 palette | Turbo, Rainbow, Sinebow, Cubehelix, Tableau10 |
all |
308 + 70 palettes | All collections |
Framework integrations
All integrations provide bidirectional conversion via From/Into. Enum-based types use TryFrom for the reverse direction. Enable all-integrations to get everything.
| Feature flag | Framework | Forward | Reverse |
|---|---|---|---|
egui-integration |
egui | Color -> Color32 |
Color32 -> Color |
plotters-integration |
plotters | Color -> RGBColor |
RGBColor -> Color |
image-integration |
image | Color -> Rgb<u8> |
Rgb<u8> -> Color |
palette-integration |
palette | Color -> Srgb<u8> |
Srgb<u8> -> Color |
bevy-color-integration |
bevy_color | Color -> Srgba |
Srgba -> Color |
iced-integration |
iced | Color -> iced::Color |
iced::Color -> Color |
macroquad-integration |
macroquad | Color -> mq::Color |
mq::Color -> Color |
tiny-skia-integration |
tiny-skia | Color -> ts::Color |
ts::Color -> Color |
wgpu-integration |
wgpu | Color -> wgpu::Color |
wgpu::Color -> Color |
slint-integration |
slint | Color -> slint::Color |
slint::Color -> Color |
ratatui-integration |
ratatui | Color -> Color::Rgb |
TryFrom |
crossterm-integration |
crossterm | Color -> Color::Rgb |
TryFrom |
colored-integration |
colored | Color -> TrueColor |
TryFrom |
owo-colors-integration |
owo-colors | Color -> Rgb |
Rgb -> Color |
termion-integration |
termion | Color -> Rgb |
Rgb -> Color |
cursive-integration |
cursive | Color -> Color::Rgb |
TryFrom |
comfy-table-integration |
comfy-table | Color -> Color::Rgb |
TryFrom |
syntect-integration |
syntect | Color -> hl::Color |
hl::Color -> Color |
serde-support |
serde | Serialize/Deserialize for meta types | |
all-integrations |
all of the above |
Binary size
Each colormap is a 256x3 = 768-byte LUT plus ~200 bytes of metadata. Approximately 1 KB per colormap.
| Feature | Maps | Size |
|---|---|---|
core (default) |
48 | ~48 KB |
all |
308 | ~308 KB |
Even with all 308 colormaps enabled, the total is smaller than a single PNG image.
Metadata
Every colormap carries structured metadata for programmatic filtering:
Citation
If you use prismatica in academic work, please cite the upstream colormap authors. Each colormap's meta.citation field contains the appropriate reference. Key citations:
- Crameri: Crameri, F. (2018). Scientific colour maps. Zenodo. doi:10.5281/zenodo.1243862
- CET: Kovesi, P. (2015). Good Colour Maps: How to Design Them. arXiv:1509.03700
- CMOcean: Thyng, K. M. et al. (2016). True colors of oceanography. Oceanography, 29(3), 10.
- CMasher: van der Velden, E. (2020). CMasher: Scientific colormaps for making accessible, informative and 'cmashing' plots. JOSS, 5(46), 2004.
For Developers
Architecture
Prismatica's core data model is simple:
- A lookup table (LUT) of 256 evenly-spaced RGB values, stored as
static [[u8; 3]; 256] - A metadata struct describing the colormap's properties
- A sampling function that interpolates between LUT entries for any input
tin[0, 1]
All colormap data is compiled into the binary as const/static arrays. There is no runtime I/O, no parsing, and no allocation for basic operations.
Module structure
src/
├── lib.rs # Crate-level docs, re-exports, feature gates
├── types.rs # Color, Colormap, ColormapMeta, ColormapKind, DiscretePalette
├── traits.rs # Framework conversion traits (feature-gated)
├── registry.rs # all_colormaps(), find_by_name(), filter functions, palette functions
├── prelude.rs # Convenience re-exports
├── integration/ # Feature-gated framework conversions (19 crates)
│
├── matplotlib/ # Feature: "matplotlib" — 8 maps
├── crameri/ # Feature: "crameri" — 40 maps
├── cet/ # Feature: "cet" — 59 maps
├── cmocean/ # Feature: "cmocean" — 22 maps
├── colorbrewer/ # Feature: "colorbrewer" — 35 maps + 35 palettes
├── cmasher/ # Feature: "cmasher" — 53 maps
├── ncar/ # Feature: "ncar" — 44 maps
├── cartocolors/ # Feature: "cartocolors" — 34 maps + 34 palettes
├── moreland/ # Feature: "moreland" — 6 maps
└── d3/ # Feature: "d3" — 7 maps + 1 palette
Code generation pipeline
Colormaps are not written by hand. A two-stage pipeline generates all colormap source code:
-
Fetch (
cargo xtask fetch [collection]): Downloads upstream data and normalizes todata/{collection}/{name}.csv(256 rows ofR,G,Bas uint8) plusdata/{collection}/{name}.json(metadata). -
Generate (
cargo xtask generate [collection]): Reads normalized CSV + JSON and emits Rust source files withconstcolormap definitions andstaticLUT arrays.
Upstream data -> cargo xtask fetch -> data/*.csv + data/*.json -> cargo xtask generate -> src/{collection}/*.rs
Data sources
| Collection | Source | Format | License |
|---|---|---|---|
| Crameri | Zenodo | 256x3 CSV (floats 0-1) | MIT |
| CET | colorcet.com | CSV (floats 0-1) | CC-BY |
| CMOcean | GitHub | Space-separated float .txt | MIT |
| ColorBrewer | colorbrewer2.org | JSON (rgb() CSS strings) | Apache-2.0 |
| Matplotlib | GitHub | Python 256x3 float arrays | CC0 |
| CMasher | GitHub | .txt LUT files (int/float) |
BSD-3 |
| Moreland | kennethmoreland.com | CSV (int 0-255) | Public domain / BSD |
| NCAR NCL | GitHub | .rgb integer tables |
Apache-2.0 |
| CartoColors | GitHub | TypeScript hex arrays | CC-BY-3.0 |
| d3 | computed locally | Cubehelix/sinebow math | ISC |
Adding new colormaps
To add a new collection:
- Add a fetch module in
xtask/src/fetch/{collection}.rs - Register it in
xtask/src/fetch/mod.rs - Run
cargo xtask fetch {collection}to populatedata/{collection}/ - Add generate module (or use the generic path) in
xtask/src/generate/ - Run
cargo xtask generate {collection}to emitsrc/{collection}/*.rs - Add a feature flag in
Cargo.tomland add to theallfeature - Add
#[cfg(feature = "...")]module declaration inlib.rs - Add the collection to
for_each_colormap()inregistry.rs
Testing
Snapshot tests use insta to detect codegen changes. After modifying the code generation pipeline, run cargo insta review to inspect and accept updated snapshots.
Code quality
Competitive positioning
| Crate | Colormaps | LUT-based | Metadata | Collections | no_std |
|---|---|---|---|---|---|
| colorous | ~40 | Partial | None | d3 only | Yes |
| colorgrad | ~40 | No (interpolated) | None | d3 + custom | No |
| scarlet | ~5 | No (computed) | None | Basic only | No |
| prismatica | 308 | Yes (256-step const) | Full | 10 collections | Yes |
Minimum supported Rust version
Rust edition 2024, targeting stable Rust 1.85+.
Support
If prismatica is useful to your projects, consider supporting development via thanks.dev.
License
This project is licensed under the GNU General Public License v3.0.
Prismatica bundles colormap data from multiple upstream sources, each with its own license. All upstream licenses are permissive (MIT, Apache-2.0, CC-BY, CC0, BSD-3, public domain) and compatible with GPL-3.0. See individual collection module docs for source URLs and license details.