Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gradient SVG is slightly inaccurate #788

Closed
fedarko opened this issue Oct 14, 2020 · 1 comment · Fixed by #789
Closed

Gradient SVG is slightly inaccurate #788

fedarko opened this issue Oct 14, 2020 · 1 comment · Fixed by #789

Comments

@fedarko
Copy link
Contributor

fedarko commented Oct 14, 2020

The actual coloring of samples is fine, I think, but the SVG gradients produced sometimes cover only ~99% of the domain, not 100%. This means that the end colors shown in the gradients are very slightly incorrect.

It's pretty confusing, because right now there are two tests that test the gradient SVG creation:

  1. In one of these tests this error is present. The returned Viridis gradient, which is used as the reference for verifying the result, ends at 99% (with #f8e725), rather than at 100% (#fee825, which is the actual end color for Viridis).

  2. In the other one of these tests, this error does not seem to be present: the color map being tested is Blues, and the minimum and maximum colors (#f7fbff and #08306b) match up with the extrema for this color map (going off what chroma.scale('blues')(0) and chroma.scale('blues')(1) return).

I think the problematic part of code is within this block:

//build the SVG showing the gradient of colors for values
var mid = (min + max) / 2;
var step = (max - min) / 100;
var stopColors = [];
for (var s = min; s <= max; s += step) {
stopColors.push(interpolator(s).hex());
}
var gradientSVG = '<defs>';
gradientSVG += '<linearGradient id="Gradient" x1="0" x2="0" y1="1" y2="0">';
for (var pos = 0; pos < stopColors.length; pos++) {
gradientSVG += '<stop offset="' + pos + '%" stop-color="' +
stopColors[pos] + '"/>';
}
gradientSVG += '</linearGradient></defs><rect id="gradientRect" ' +

The first for loop seems suspicious to me. I'm not completely sure yet what's wrong with this code, but it looks like there might be precision issues with the s <= max check: since the data used for the test that failed had a step of (4 - 0) / 100 = 0.04, while the data used for the test that succeeded had a relatively larger step of (50 - 0) / 100 = 0.5.

I think it would make the most sense to just remove some of this code and use chroma.scale.colors() to do the work for us:

 var stopColors = interpolator.colors(101);
// Now we can construct gradientSVG just like we did before, with the final color (corresponding
// to the maximum value) being placed at 100%

Can put together a PR for this tomorrow if you'd like.

This impacts Empress as well, since the gradient SVG code there was adapted from this code.

@ElDeveloper
Copy link
Member

ElDeveloper commented Oct 14, 2020 via email

fedarko added a commit to fedarko/emperor that referenced this issue Oct 14, 2020
Closes biocore#788. Also adds some test / documentation.
fedarko added a commit to fedarko/emperor that referenced this issue Mar 5, 2021
ElDeveloper pushed a commit that referenced this issue Mar 5, 2021
)

* BUG/TST: Force gradient SVG to use full [0%, 100%]

Closes #788. Also adds some test / documentation.

* STY: fix egregiously long line for gjslint

* TST: fix grammar in test title

* DOC: Clarify a test comment slightly; travis kick

now that build problems seem to have been addressed

* DOC: Travis kick; fix grammar/Q2 link in README

* REL: add note to changelog re: #788

* DOC: while we're at it, update the q2 docs link

* REL: mention README changes in the ChangeLog
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants