Skip to content

A flexible library to map numerical values to colors

Notifications You must be signed in to change notification settings

alesgenova/colormap

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

53 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CircleCI codecov Language grade: JavaScript lerna

ColorMap

A flexible library to map numerical values to colors

Packages

Package Version Description
@colormap/core npm package Core functions and utilities
@colormap/presets npm package Popular predefined colormaps

Install

Install the @colormap/core package

npm install @colormap/core

Optionally install @colormap/preset to have popular colormaps from matplotlib readily available

npm install @colormap/preset

Basic Usage

import { createColorMap, createOpacityMap, createColorOpacityMap, linearScale } from "@colormap/core";

let colors = [
  [1, 0, 0],
  [0, 1, 0],
  [0, 0, 1]
];
let opacities = [1, 0, 1];
let domain = [0, 100];
let range = [0, 1];
let scale = linearScale(domain, range);
let colorMap = createColorMap(colors, scale);
let opacityMap = createOpacityMap(opacities, scale);
let colorOpacityMap = createColorOpacityMap(colorMap, opacityMap);
let values = [0, 25, 50, 75, 100];
console.log(values.map(v => colorMap(v)));
// [[1, 0, 0], [0.5, 0.5, 0], [0, 1, 0], [0, 0.5, 0.5], [0, 0, 1]]
console.log(values.map(v => opacityMap(v)));
// [1, 0.5, 0, 0.5, 1]
console.log(values.map(v => colorOpacityMap(v)));
// [[1, 0, 0, 1], [0.5, 0.5, 0, 0.5], [0, 1, 0, 0], [0, 0.5, 0.5, 0.5], [0, 0, 1, 1]]

Advanced Usage

Specify color/opacity maps by arbitrary nodes

Colors and opacities array don't necessarily need to span evenly the [0, 1] interval. Maps can be generated from arbitrary nodes.

import { createColorMap, linearScale } from "@colormap/core";

let colors = [
  { value: -1.0, mapped: [0, 0, 1] },
  { value: 0.0, mapped: [1, 0, 0] },
  { value: 0.5, mapped: [0, 1, 0] },
  { value: 2.0, mapped: [0, 0, 1] }
];
let domain = [0, 100];
let range = [-1, 2];
let scale = linearScale(domain, range);
let colorMap = createColorMap(colors, scale);
let values = [0, 25, 50, 75, 100];
console.log(values.map(v => colorMap(v)));
// [[0, 0, 1], [0.75, 0, 0.25], [0, 1, 0], [0, 0.5, 0.5], [0, 0, 1]]

Node Mixers

When the scalar value is between two colormap nodes, we can have several strategies to mix the colors in the two nodes. By default a linear interpolation between nodes will be done. But this behavior can be overridden by passing a function as a third parameter to createColorMap(colors, scale, mixer).

The signature of the mixer function is: function(value: number, lowerNodeValue: number, upperNodeValue: number) : [number, number].

Four mixers are provided for convenience.

import { linearMixer, roundMixer, floorMixer, ceilMixer } from '@colormap/core';

let colors = [[1, 0, 0], [1, 1, 0], [0, 1, 0], [0, 1, 1], [0, 0, 1]];
let scale = linearScale([0, 1], [0, 1]);
let colorMap = createColorMap(colors, scale, linearMixer);

Below is the effect these mixers have on the same 5-node colormap:

  • linearMixer (default)

  • roundMixer

  • floorMixer

  • ceilMixer

Preset Colormaps

A set of popular colormaps from matplotlib are exported by the @colormap/presets package.

import { createColorMap, linearScale } from "@colormap/core";
import { viridis, cividis, plasma, inferno, magma, blackWhite } from "@colormap/presets";

let scale = linearScale([0, 100], [0, 1]);
let colorMap = createColorMap(viridis, scale);
console.log([0, 100].map(v => colorMap(v)));
// [[0.267004, 0.004874, 0.329415], [0.993248, 0.906157, 0.143936]]
  • viridis

  • cividis

  • plasma

  • inferno

  • magma

  • blackWhite