d3 / d3-scale-chromatic

Sequential, diverging and categorical color scales.
https://d3js.org/d3-scale-chromatic
Other
798 stars 107 forks source link

real interpolation in MPL colormaps #36

Open mkomo opened 3 years ago

mkomo commented 3 years ago

The four BIDS colormaps [viridis, magma, inferno, plasma] are each defined by arrays of 256 colors.*

These colormaps all have visible color banding (as seen in the images referenced by the d3-scale-chromatic README). By switching to the standard ramp function for each of these scales, banding is significantly decreased:

*In a 24-bit color space, viridis is actually only 254 colors because two of the colors [#26828e, #20928c] are present twice due to rounding (this is true in the original python as well as in the D3 implementation.)

mkomo commented 3 years ago

Differences between existing images and new images

magick compare -metric rmse inferno.png img/inferno.png inferno-difference.png inferno-difference

magick compare -metric rmse magma.png img/magma.png magma-difference.png magma-difference

magick compare -metric rmse plasma.png img/plasma.png plasma-difference.png plasma-difference

magick compare -metric rmse viridis.png img/viridis.png viridis-difference.png viridis-difference

These differences are due to the new color interpolation.

mkomo commented 3 years ago

Test code to determine number of distinct colors in a given chromatic scale:

const getAllScaleColorsBetween = (scale, start=0, end=1) => {
  const s = scale(start),
    e = scale(end);
  if (s == e) {
    return {[s]: start};
  } else if (colorDiff(s, e) == 1 || end - start < Number.EPSILON) {
    return {[s]: start, [e]: end};
  } else {
    const mid = (start + end) / 2;
    return {...getAllScaleColorsBetween(scale, start, mid), ...getAllScaleColorsBetween(scale, mid, end)};
  }
}
const colorDiff = (s, e) => {
  const c1 = d3.color(s), c2 = d3.color(e);
  return Math.abs(c1.r - c2.r) + Math.abs(c1.g - c2.g) + Math.abs(c1.b - c2.b);
}
Fil commented 3 years ago

built here https://observablehq.com/d/e9aa5c89fc7d6f9c if someone wants to test things (feel free to send suggestions)

On my screen and with my eyes, I don't see any difference, in fact I don't see any banding in the original ramps 👓. So thank you for the code that counts the colors!