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 ¶
- 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) 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 ¶
This section is empty.
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)
func (*BoundaryNorm) Inverse ¶
func (n *BoundaryNorm) Inverse(t float64) float64
func (*BoundaryNorm) Norm ¶
func (n *BoundaryNorm) Norm(v float64) float64
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
}
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 ( // PerceptuallyUniform — matplotlib defaults. Viridis Cmap Plasma Cmap Inferno Cmap Magma Cmap Cividis Cmap // Sequential — ColorBrewer 9-class. Greys Cmap Blues Cmap Greens Cmap Oranges Cmap Reds Cmap Purples Cmap YlGn Cmap YlGnBu Cmap YlOrBr Cmap YlOrRd Cmap // Diverging — ColorBrewer 11-class + matplotlib originals. RdBu Cmap RdYlBu Cmap RdYlGn Cmap Spectral Cmap BrBG Cmap PiYG Cmap PRGn Cmap PuOr Cmap RdGy Cmap Coolwarm Cmap Bwr Cmap // Qualitative. Tab10 Cmap Tab20 Cmap Tab20b Cmap Tab20c Cmap Set1 Cmap Set2 Cmap Set3 Cmap Paired Cmap Pastel1 Cmap Pastel2 Cmap Accent Cmap Dark2 Cmap OkabeIto Cmap )
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)
func (*LinearNorm) Inverse ¶
func (n *LinearNorm) Inverse(t float64) float64
func (*LinearNorm) Norm ¶
func (n *LinearNorm) Norm(v float64) float64
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
func (*LinearSegmentedCmap) N ¶
func (c *LinearSegmentedCmap) N() int
func (*LinearSegmentedCmap) Name ¶
func (c *LinearSegmentedCmap) Name() string
func (*LinearSegmentedCmap) Resampled ¶
func (c *LinearSegmentedCmap) Resampled(n int) Cmap
func (*LinearSegmentedCmap) Reversed ¶
func (c *LinearSegmentedCmap) Reversed() Cmap
func (*LinearSegmentedCmap) WithExtremes ¶
func (c *LinearSegmentedCmap) WithExtremes(under, over, bad *gg.RGBA) Cmap
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
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) N ¶
func (c *ListedCmap) N() int
func (*ListedCmap) Name ¶
func (c *ListedCmap) Name() string
func (*ListedCmap) Resampled ¶
func (c *ListedCmap) Resampled(n int) Cmap
func (*ListedCmap) Reversed ¶
func (c *ListedCmap) Reversed() Cmap
func (*ListedCmap) WithExtremes ¶
func (c *ListedCmap) WithExtremes(under, over, bad *gg.RGBA) Cmap
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) 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)
func (*TwoSlopeNorm) Inverse ¶
func (n *TwoSlopeNorm) Inverse(t float64) float64
func (*TwoSlopeNorm) Norm ¶
func (n *TwoSlopeNorm) Norm(v float64) float64