8000 8000
Skip to content

real interpolation in MPL colormaps - #36

Open
mkomo wants to merge 1 commit into
d3:mainfrom
mkomo:interpolate
Open

real interpolation in MPL colormaps#36
mkomo wants to merge 1 commit into
d3:mainfrom
mkomo:interpolate

Conversation

@mkomo
@mkomo mkomo commented Apr 17, 2021
Copy link
Copy Markdown

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:

  • viridis 254 -> 650 distinct colors
    viridis

  • magma 256 -> 717 distinct colors
    magma

  • inferno 256 -> 861 distinct colors
    inferno

  • plasma 256 -> 642 distinct colors
    plasma

*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
mkomo commented Apr 17, 2021
Copy link
Copy Markdown
Author

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
mkomo commented Apr 17, 2021
Copy link
Copy Markdown
Author

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
Fil commented Apr 17, 2021
Copy link
Copy Markdown
Member

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!

@Fil Fil mentioned this pull request Apr 27, 2021
5 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

0