abachrome

How do I generate a color palette with smooth interpolation in Ruby?

Abachrome::Palette holds an ordered list of colors and generates interpolated steps between them. Because blending happens in OKLCH by default, every intermediate color has consistent perceived lightness and saturation.

Basic Palette Generation

require 'abachrome'

stops = [
  Abachrome.from_oklch(0.4, 0.15, 260),  # dark blue
  Abachrome.from_oklch(0.7, 0.18, 145),  # mid green
  Abachrome.from_oklch(0.9, 0.12, 80),   # light yellow
]

palette = Abachrome::Palette.new(stops)
steps   = palette.interpolate(steps: 11)

steps.each do |color|
  puts Abachrome::Outputs::CSS.format(color.to_srgb)
end

Outputting as CSS Custom Properties

palette = Abachrome::Palette.new([
  Abachrome.from_hex('#264653'),
  Abachrome.from_hex('#2a9d8f'),
  Abachrome.from_hex('#e9c46a'),
  Abachrome.from_hex('#f4a261'),
  Abachrome.from_hex('#e76f51'),
])

ramp = palette.interpolate(steps: 9)

css = ramp.each_with_index.map do |color, i|
  "  --color-#{i + 1}: #{Abachrome::Outputs::CSS.format(color.to_srgb)};"
end.join("\n")

puts ":root {\n#{css}\n}"

Diverging Scales for Data Visualization

A two-stop diverging palette (negative → neutral → positive) works well for heatmaps and choropleth maps:

negative = Abachrome.from_oklch(0.55, 0.22, 20)   # warm red
neutral  = Abachrome.from_oklch(0.92, 0.01, 0)    # near-white
positive = Abachrome.from_oklch(0.55, 0.20, 250)  # cool blue

scale = Abachrome::Palette.new([negative, neutral, positive])
        .interpolate(steps: 11)

Notes

  • The steps count includes the original anchor colors; pass a higher number for finer gradients.
  • Always call .to_srgb before formatting for CSS output — OKLCH coordinates are not valid in standard CSS without the oklch() function.