Documentation
¶
Overview ¶
Package colormap provides a matplotlib-style colormap and color-scale API for the ggplot grammar of graphics pipeline.
Core abstractions ¶
- Cmap — maps a normalized t in [0,1] to an gg.RGBA color. Implementations: LinearSegmentedCmap (256-entry LUT, continuous) and ListedCmap (discrete).
- Norm — maps an arbitrary scalar value into [0,1]. Implementations include LinearNorm, LogNorm, PowerNorm, TwoSlopeNorm, BoundaryNorm, AsinhNorm.
- Scale — composes a Norm and a Cmap and adds dataset training. This is the ggplot analogue of matplotlib's ScalarMappable and is what user code actually attaches to a [Plot] via .ScaleColor / .ScaleFill / .ScaleColorManual.
Categories ¶
Cmaps are grouped into matplotlib's standard categories:
- PerceptuallyUniform: viridis, plasma, inferno, magma, cividis, turbo
- Sequential: greys, blues, greens, oranges, reds, purples, ylgn, ylgnbu, ylorbr, ylorrd, bugn, gnbu, bupu, orrd, pubu, pubugn, purd, rdpu
- Diverging: rdbu, rdylbu, spectral, coolwarm, brbg, piyg, prgn, puor, rdgy, rdylgn, bwr
- Cyclic: twilight, twilight_shifted, hsv
- Qualitative: tab10, tab20, set1, set2, set3, paired, pastel1, pastel2, accent, dark2, okabe_ito
Registry ¶
Built-in cmaps register themselves at init time. Look them up by name with Resolve (the suffix "_r" returns the reversed colormap, e.g. "viridis_r"):
cm, err := colormap.Resolve("viridis")
cm := colormap.MustResolve("plasma_r")
or use the typed exported variables directly:
cm := colormap.Viridis cm := colormap.Plasma.Reversed()
Color literal parsing ¶
Parse accepts hex strings (delegates to gg.ParseHex), CSS / X11 named colors, the matplotlib "tab:blue" / "tab:orange" aliases, and rgb()/rgba()/ hsl() functional forms. It returns gg.RGBA (float-space color) so the result interoperates directly with the renderer without uint8 truncation.
Design conventions ¶
All Cmap methods return gg.RGBA (not image/color.Color) so the rendering pipeline can stay in float space. gg.RGBA itself satisfies the standard color.Color interface, so values pass through canvas.SetColor unchanged.
LUT data is vendored from matplotlib's BSD/CC0 reference data. The package does not reimplement hex parsing or RGB lerping — those come from gg.
Index ¶
- Variables
- func MustParse(s string) gg.RGBA
- func MustRegister(c Cmap)
- func Names() []string
- func NamesByCategory(cat Category) []string
- func Parse(s string) (gg.RGBA, error)
- func ParseRGB(spec string, defR, defG, defB float64) (r, g, b float64)
- func Register(c Cmap) error
- type AsinhNorm
- type BoundaryNorm
- type Category
- type Cmap
- type Color
- type LinearNorm
- type LinearSegmentedCmap
- func (c *LinearSegmentedCmap) At(t float64) gg.RGBA
- func (c *LinearSegmentedCmap) Category() Category
- func (c *LinearSegmentedCmap) N() int
- func (c *LinearSegmentedCmap) Name() string
- func (c *LinearSegmentedCmap) Resampled(n int) Cmap
- func (c *LinearSegmentedCmap) Reversed() Cmap
- func (c *LinearSegmentedCmap) WithExtremes(under, over, bad *gg.RGBA) Cmap
- type ListedCmap
- func (c *ListedCmap) At(t float64) gg.RGBA
- func (c *ListedCmap) Category() Category
- func (c *ListedCmap) Color(i int) gg.RGBA
- func (c *ListedCmap) Colors() []gg.RGBA
- func (c *ListedCmap) N() int
- func (c *ListedCmap) Name() string
- func (c *ListedCmap) Resampled(n int) Cmap
- func (c *ListedCmap) Reversed() Cmap
- func (c *ListedCmap) WithExtremes(under, over, bad *gg.RGBA) Cmap
- type LogNorm
- type Norm
- type PowerNorm
- type Scale
- func (s *Scale) At(v any) gg.RGBA
- func (s *Scale) Categories() []string
- func (s *Scale) Cmap() Cmap
- func (s *Scale) Discrete() bool
- func (s *Scale) Norm() Norm
- func (s *Scale) SetCmap(c Cmap)
- func (s *Scale) SetCycle(cycle bool)
- func (s *Scale) SetNAColor(c *gg.RGBA)
- func (s *Scale) SetNorm(n Norm)
- func (s *Scale) SetOverride(label string, c gg.RGBA)
- func (s *Scale) Train(col dataset.AnyColumn) error
- type TwoSlopeNorm
Constants ¶
This section is empty.
Variables ¶
var ( // ErrEmptyColor is returned for empty color strings. ErrEmptyColor = errors.New("colormap: empty color string") // ErrUnknownAlias is returned for unrecognized color aliases. ErrUnknownAlias = errors.New("colormap: unknown color alias") // ErrParseColor is returned when a color string cannot be parsed. ErrParseColor = errors.New("colormap: cannot parse color") // ErrMalformedLiteral is returned for malformed color literals. ErrMalformedLiteral = errors.New("colormap: malformed color literal") // ErrComponentCount is returned when a color has the wrong number of components. ErrComponentCount = errors.New("colormap: wrong number of color components") // ErrNilCmap is returned when a nil Cmap is registered. ErrNilCmap = errors.New("colormap: cannot register nil Cmap") // ErrEmptyName is returned for empty colormap names. ErrEmptyName = errors.New("colormap: empty name") // ErrAlreadyRegistered is returned when a name is already registered. ErrAlreadyRegistered = errors.New("colormap: name already registered") // ErrNotFound is returned when a colormap is not found. ErrNotFound = errors.New("colormap: colormap not found") // ErrPositiveRequired is returned when strictly positive values are needed. ErrPositiveRequired = errors.New("colormap: strictly positive values required") // ErrInvalidRange is returned when a normalization range is invalid. ErrInvalidRange = errors.New("colormap: invalid range") // ErrNonNumeric is returned for non-numeric column types. ErrNonNumeric = errors.New("colormap: non-numeric column type") )
Sentinel errors for the colormap package.
Functions ¶
func MustRegister ¶
func MustRegister(c Cmap)
MustRegister registers c and panics on error. Intended for init-time use.
func Names ¶
func Names() []string
Names returns all registered cmap names sorted alphabetically. The "_r" reversed forms are not enumerated — they are derivable from each base name.
func NamesByCategory ¶
NamesByCategory returns the registered cmap names whose Category matches the argument, sorted alphabetically.
func Parse ¶
Parse converts a color literal to gg.RGBA. Accepted forms:
- Hex: "#RGB", "#RGBA", "#RRGGBB", "#RRGGBBAA" (delegates to gg.ParseHex; leading '#' optional).
- CSS / X11 named colors: "red", "coral", "rebeccapurple", … (147 names).
- Matplotlib aliases: "tab:blue", "tab:orange", … through "tab:cyan".
- Functional rgb / rgba: "rgb(255,0,0)", "rgba(0,128,0,0.5)". Channels accept 0–255 integers or "<n>%" (0–100).
- Functional hsl: "hsl(120,100%,50%)" — h in degrees [0,360), s and l in percent.
Empty strings return an error. Comparisons are case-insensitive for named colors and the leading function keyword.
func ParseRGB ¶
ParseRGB parses a color spec and returns its normalized [0,1] RGB components. On empty or invalid input, defR/defG/defB are returned unchanged.
Types ¶
type AsinhNorm ¶
type AsinhNorm struct {
LinearWidth float64
Vmin, Vmax float64
// contains filtered or unexported fields
}
AsinhNorm performs a smooth asinh (inverse-hyperbolic-sine) transform that behaves linearly near zero and logarithmically far from zero — useful for data spanning many decades that includes zeros or negatives.
type BoundaryNorm ¶
type BoundaryNorm struct {
Boundaries []float64 // ascending; len >= 2
Ncolors int // typically len(Boundaries)-1
Clip bool // clamp out-of-range to nearest boundary
}
BoundaryNorm bins v into one of len(Boundaries)-1 cells. The result is rounded to one of Ncolors discrete fractions so a Cmap.Resampled(Ncolors) produces a stepped colorbar with breakpoints at Boundaries.
func (*BoundaryNorm) Bounds ¶
func (n *BoundaryNorm) Bounds() (float64, float64)
Bounds returns the first and last boundary values.
func (*BoundaryNorm) Inverse ¶
func (n *BoundaryNorm) Inverse(t float64) float64
Inverse maps t in [0, 1] back to the midpoint of the matching boundary cell.
func (*BoundaryNorm) Norm ¶
func (n *BoundaryNorm) Norm(v float64) float64
Norm maps v into discrete boundary cells as a fraction of [0, 1].
type Category ¶
type Category int
Category groups colormaps along matplotlib's standard taxonomy. Used by Cmap.Category and NamesByCategory.
const ( // Sequential covers smooth, monotonic-lightness colormaps suitable for // continuous, ordered data without a natural midpoint (Blues, Reds, ...). Sequential Category = iota // PerceptuallyUniform colormaps preserve the perception of equal data // differences across the range (viridis, plasma, inferno, magma, cividis). PerceptuallyUniform // Diverging colormaps emphasize departure from a meaningful midpoint // (RdBu, Spectral, ...). Diverging // Cyclic colormaps wrap (twilight, hsv). Cyclic // Qualitative covers discrete categorical palettes (tab10, Set1, ...). Qualitative // Miscellaneous holds everything that doesn't fit cleanly elsewhere // (turbo, terrain, etc.). Miscellaneous )
type Cmap ¶
type Cmap interface {
// At samples the colormap at t. t outside [0,1] is clamped (or replaced
// by Under/Over). NaN inputs return Bad.
At(t float64) gg.RGBA
// Name returns the registered identifier.
Name() string
// N returns the number of distinct colors. 256 for LUT-backed cmaps,
// len(colors) for [ListedCmap].
N() int
// Category returns the matplotlib taxonomy bucket.
Category() Category
// Reversed returns a Cmap with the gradient flipped (At(t) -> At(1-t)).
Reversed() Cmap
// Resampled returns a Cmap that quantizes t into n equally-sized bins.
// Useful for legend swatches or stepped color bars.
Resampled(n int) Cmap
// WithExtremes returns a Cmap with explicit colors for out-of-range and
// NaN inputs. Pass nil for any to keep the default (clamped At(0)/At(1)
// for under/over, transparent for bad).
WithExtremes(under, over, bad *gg.RGBA) Cmap
}
Cmap is a colormap that maps values in [0, 1] to RGBA colors.
Implementations should:
- Clamp t outside [0,1] to At(0)/At(1), or substitute Under/Over if set via WithExtremes.
- Return Bad (or fully-transparent black) when t is NaN.
- Be safe for concurrent reads — Cmap values are immutable; mutators (Reversed, Resampled, WithExtremes) return a new Cmap.
var ( // Viridis is a perceptually-uniform sequential colormap (matplotlib default). Viridis Cmap // Plasma is a perceptually-uniform sequential colormap. Plasma Cmap // Inferno is a perceptually-uniform sequential colormap. Inferno Cmap // Magma is a perceptually-uniform sequential colormap. Magma Cmap // Cividis is a perceptually-uniform sequential colormap (colorblind-safe). Cividis Cmap // Greys is a sequential single-hue colormap (ColorBrewer 9-class). Greys Cmap // Blues is a sequential single-hue colormap (ColorBrewer 9-class). Blues Cmap // Greens is a sequential single-hue colormap (ColorBrewer 9-class). Greens Cmap // Oranges is a sequential single-hue colormap (ColorBrewer 9-class). Oranges Cmap // Reds is a sequential single-hue colormap (ColorBrewer 9-class). Reds Cmap // Purples is a sequential single-hue colormap (ColorBrewer 9-class). Purples Cmap // YlGn is a sequential multi-hue colormap (ColorBrewer 9-class). YlGn Cmap // YlGnBu is a sequential multi-hue colormap (ColorBrewer 9-class). YlGnBu Cmap // YlOrBr is a sequential multi-hue colormap (ColorBrewer 9-class). YlOrBr Cmap // YlOrRd is a sequential multi-hue colormap (ColorBrewer 9-class). YlOrRd Cmap // RdBu is a diverging colormap from red through white to blue. RdBu Cmap // RdYlBu is a diverging colormap from red through yellow to blue. RdYlBu Cmap // RdYlGn is a diverging colormap from red through yellow to green. RdYlGn Cmap // Spectral is a diverging rainbow-like colormap. Spectral Cmap // BrBG is a diverging colormap from brown through white to blue-green. BrBG Cmap // PiYG is a diverging colormap from pink through white to yellow-green. PiYG Cmap // PRGn is a diverging colormap from purple through white to green. PRGn Cmap // PuOr is a diverging colormap from purple through white to orange. PuOr Cmap // RdGy is a diverging colormap from red through white to grey. RdGy Cmap // Coolwarm is a diverging colormap from cool blue to warm red. Coolwarm Cmap // Bwr is a diverging colormap from blue through white to red. Bwr Cmap // Tab10 is a 10-color qualitative palette from Tableau. Tab10 Cmap // Tab20 is a 20-color qualitative palette from Tableau. Tab20 Cmap // Tab20b is a 20-color qualitative palette (variant b) from Tableau. Tab20b Cmap // Tab20c is a 20-color qualitative palette (variant c) from Tableau. Tab20c Cmap // Set1 is a qualitative palette from ColorBrewer. Set1 Cmap // Set2 is a qualitative palette from ColorBrewer. Set2 Cmap // Set3 is a qualitative palette from ColorBrewer. Set3 Cmap // Paired is a qualitative paired-color palette from ColorBrewer. Paired Cmap // Pastel1 is a qualitative pastel palette from ColorBrewer. Pastel1 Cmap // Pastel2 is a qualitative pastel palette from ColorBrewer. Pastel2 Cmap // Accent is a qualitative accent palette from ColorBrewer. Accent Cmap // Dark2 is a qualitative dark palette from ColorBrewer. Dark2 Cmap // OkabeIto is a colorblind-safe qualitative palette. OkabeIto Cmap // Observable10 is a qualitative palette optimized for online displays. Observable10 Cmap // Twilight is a perceptually-uniform cyclic colormap. 0 and 1 map to the // same color, making it suitable for circular variables (phase, angle). Twilight Cmap // Phase is an HSL-based cyclic colormap. Wraps smoothly through hues. Phase Cmap // Turbo is a high-dynamic-range sequential colormap (Mikhailov 2019). // Excellent for revealing fine structure in engineering/dashboard contexts // but not colorblind-safe. Prefer Viridis/Cividis for scientific work. Turbo Cmap // JetLegacy is the classic MATLAB jet colormap. It has known perceptual // defects: non-monotonic luminance, colorblind-unsafe, and phantom // banding artifacts. Prefer Turbo, Viridis, or Inferno for new work. JetLegacy Cmap )
func Gradient ¶ added in v0.0.7
Gradient returns a 2-stop continuous colormap that interpolates between low and high in CIELAB color space. CIELAB interpolation is perceptually uniform — equal steps in t produce equal perceived color differences.
func Gradient2 ¶ added in v0.0.7
Gradient2 returns a 3-stop diverging colormap that interpolates through low → mid → high in CIELAB color space. The midpoint is at t=0.5.
func GradientN ¶ added in v0.0.7
GradientN returns an N-stop continuous colormap from evenly-spaced color stops, interpolated in CIELAB color space. Panics if len(colors) < 2.
func MustResolve ¶
MustResolve is like Resolve but panics on error.
type Color ¶
Color is the canonical color type used throughout this package. It is a type alias for gg.RGBA (float-space components in [0,1] plus alpha), so user code can refer to colormap.Color without importing gg directly. The alias keeps the rendering pipeline in float space — no uint8 truncation when sampling or interpolating colormaps.
type LinearNorm ¶
type LinearNorm struct {
Vmin, Vmax float64
// contains filtered or unexported fields
}
LinearNorm scales v linearly between Vmin and Vmax. Zero value is valid: it auto-trains on the first Train() call.
func (*LinearNorm) Bounds ¶
func (n *LinearNorm) Bounds() (float64, float64)
Bounds returns the current trained data range.
func (*LinearNorm) Inverse ¶
func (n *LinearNorm) Inverse(t float64) float64
Inverse maps t in [0, 1] back to the linear data range.
func (*LinearNorm) Norm ¶
func (n *LinearNorm) Norm(v float64) float64
Norm maps v linearly to [0, 1] between Vmin and Vmax.
type LinearSegmentedCmap ¶
type LinearSegmentedCmap struct {
// contains filtered or unexported fields
}
LinearSegmentedCmap is a continuous colormap backed by a 256-entry RGB LUT. It is the standard backing type for matplotlib's perceptually-uniform, sequential, diverging, and cyclic colormaps.
func NewLinearSegmented ¶
func NewLinearSegmented(name string, cat Category, lut [256][3]uint8) *LinearSegmentedCmap
NewLinearSegmented constructs a colormap from a 256-entry LUT.
func (*LinearSegmentedCmap) At ¶
func (c *LinearSegmentedCmap) At(t float64) gg.RGBA
At samples the colormap by linearly interpolating between adjacent LUT entries.
func (*LinearSegmentedCmap) Category ¶
func (c *LinearSegmentedCmap) Category() Category
Category returns the taxonomy bucket.
func (*LinearSegmentedCmap) N ¶
func (c *LinearSegmentedCmap) N() int
N returns the number of distinct LUT entries (always 256).
func (*LinearSegmentedCmap) Name ¶
func (c *LinearSegmentedCmap) Name() string
Name returns the registered identifier.
func (*LinearSegmentedCmap) Resampled ¶
func (c *LinearSegmentedCmap) Resampled(n int) Cmap
Resampled returns a ListedCmap that quantizes into n bins.
func (*LinearSegmentedCmap) Reversed ¶
func (c *LinearSegmentedCmap) Reversed() Cmap
Reversed returns a new colormap with the LUT order flipped.
func (*LinearSegmentedCmap) WithExtremes ¶
func (c *LinearSegmentedCmap) WithExtremes(under, over, bad *gg.RGBA) Cmap
WithExtremes returns a copy with explicit under/over/bad colors.
type ListedCmap ¶
type ListedCmap struct {
// contains filtered or unexported fields
}
ListedCmap is a discrete colormap defined by an explicit color list. It is the backing type for qualitative palettes (tab10, Set1, etc.) and also for resampled continuous cmaps.
func NewListed ¶
func NewListed(name string, cat Category, colors []gg.RGBA) *ListedCmap
NewListed constructs a discrete colormap from a slice of colors. The slice is copied; the caller may mutate the input afterwards safely.
func (*ListedCmap) At ¶
func (c *ListedCmap) At(t float64) gg.RGBA
At returns the i-th color where i = floor(t * N). t in [0,1] maps to indices 0..N-1.
func (*ListedCmap) Category ¶
func (c *ListedCmap) Category() Category
Category returns the taxonomy bucket.
func (*ListedCmap) Color ¶
func (c *ListedCmap) Color(i int) gg.RGBA
Color returns the i-th color directly, cycling i modulo N. Use this when applying a qualitative palette to discrete categories.
func (*ListedCmap) Colors ¶
func (c *ListedCmap) Colors() []gg.RGBA
Colors returns a copy of the color list.
func (*ListedCmap) Name ¶
func (c *ListedCmap) Name() string
Name returns the registered identifier.
func (*ListedCmap) Resampled ¶
func (c *ListedCmap) Resampled(n int) Cmap
Resampled returns a new ListedCmap that quantizes into n bins.
func (*ListedCmap) Reversed ¶
func (c *ListedCmap) Reversed() Cmap
Reversed returns a new colormap with the color order flipped.
func (*ListedCmap) WithExtremes ¶
func (c *ListedCmap) WithExtremes(under, over, bad *gg.RGBA) Cmap
WithExtremes returns a copy with explicit under/over/bad colors.
type LogNorm ¶
type LogNorm struct {
Vmin, Vmax float64
// contains filtered or unexported fields
}
LogNorm performs base-10 log scaling between Vmin and Vmax. Vmin must be strictly positive after training; values v <= 0 yield NaN.
type Norm ¶
type Norm interface {
// Norm transforms v -> [0,1]. NaN is returned as NaN.
Norm(v float64) float64
// Inverse maps t in [0,1] back to data space.
Inverse(t float64) float64
// Bounds returns the current trained data range.
Bounds() (vmin, vmax float64)
// Train expands the bounds to cover values in col. Successive Train
// calls accumulate (data range only grows).
Train(col dataset.AnyColumn) error
}
Norm transforms an arbitrary scalar v into the unit interval [0,1] for input to a Cmap. Out-of-range values may be returned outside [0,1] — the consuming Cmap will clamp them or substitute Under/Over via [Cmap.WithExtremes].
type PowerNorm ¶
type PowerNorm struct {
Gamma float64
Vmin, Vmax float64
// contains filtered or unexported fields
}
PowerNorm scales v with a power-law gamma between Vmin and Vmax. Equivalent to matplotlib's PowerNorm. Useful for emphasizing small or large values.
type Scale ¶
type Scale struct {
// contains filtered or unexported fields
}
Scale composes a Norm and a Cmap into a dataset-aware color mapper. It is the primary user-facing type produced by NewContinuous, NewDiscrete, and NewManual — and the value attached to a Plot via .ScaleColor / .ScaleFill / .ScaleColorManual.
Scale supports three usage modes:
- Continuous: a Norm transforms numeric values into [0,1]; the Cmap samples a color at that t.
- Discrete: string category labels are encoded into the index space of a ListedCmap. Cycling reuses colors when categories outnumber palette entries.
- Manual: specific labels are pinned to specific gg.RGBA values via Scale.SetOverride. Overrides take precedence over both modes above in Scale.At.
func NewContinuous ¶
NewContinuous returns a Scale that maps numeric data through n into the unit interval, then samples c at the resulting t. If n is nil, a default LinearNorm is created.
func NewDiscrete ¶
NewDiscrete returns a Scale that maps category labels through c. Labels are encoded by their first-seen position; positions modulo c.N() select a color from c. Use Scale.SetCycle to control whether the palette cycles (default: cycles).
func NewManual ¶
NewManual returns a Scale where every category label has an explicit color. Labels not in m fall back to a default Tab10 palette in the order they are trained.
func (*Scale) At ¶
At maps a value to a color. Accepts string, float64, int64, int, bool, or nil. The dispatch is:
- if v is a string and an override exists, return the override;
- else if Discrete, encode as a label (registering it on first sight) and look up via the underlying ListedCmap or falling back to cmap.At(idx/N);
- else (continuous), pass v through Norm and sample Cmap.At.
NaN inputs sample the colormap's Bad slot.
func (*Scale) Categories ¶
Categories returns the list of trained category labels in encounter order. Empty for continuous scales.
func (*Scale) Norm ¶
Norm returns the underlying Norm. Returns nil for purely discrete scales that were never given one.
func (*Scale) SetCycle ¶
SetCycle controls whether discrete category index values wrap modulo the palette size. When false, indices beyond the palette return the last color.
func (*Scale) SetNAColor ¶ added in v0.0.7
SetNAColor sets the color to use for missing/null/NaN values. Pass nil to revert to the cmap's default NaN color.
func (*Scale) SetNorm ¶
SetNorm replaces the underlying Norm. Only meaningful for continuous scales.
func (*Scale) SetOverride ¶
SetOverride pins label to a specific color, overriding any computed value. Overrides apply in both continuous and discrete modes.
type TwoSlopeNorm ¶
type TwoSlopeNorm struct {
Vcenter float64
Vmin, Vmax float64
// contains filtered or unexported fields
}
TwoSlopeNorm normalises v asymmetrically around Vcenter — values below the center fill [0, 0.5] and values above fill [0.5, 1]. Standard choice for diverging colormaps where zero (or another anchor) should sit on the neutral midpoint regardless of how lopsided the data is.
func (*TwoSlopeNorm) Bounds ¶
func (n *TwoSlopeNorm) Bounds() (float64, float64)
Bounds returns the current trained data range.
func (*TwoSlopeNorm) Inverse ¶
func (n *TwoSlopeNorm) Inverse(t float64) float64
Inverse maps t in [0, 1] back to the two-slope data range.
func (*TwoSlopeNorm) Norm ¶
func (n *TwoSlopeNorm) Norm(v float64) float64
Norm maps v to [0, 1] with an asymmetric split at Vcenter.