-
Notifications
You must be signed in to change notification settings - Fork 106
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
Calculate color with two variables (t1, t2)? #32
Comments
I was looking at a similar problem lately, and have been meaning to try a solution where two separate scales are used, then the outputs can be blended into a matrix like the one you shared. I'm not sure what the best way of blending the colors is, or if there's any utility that does this inside D3 (color interpolate maybe?), but I did come across this neat library: https://github.com/Loilo/color-blend Tangentially related: Will post here if I find anything more. |
Oh, here are some things https://observablehq.com/search?query=bivariate |
In particular https://observablehq.com/@d3/bivariate-choropleth |
And there's this:
From https://observablehq.com/@benjaminadk/bivariate-choropleth-color-generator This blends the colors using https://vis4.net/chromajs/#chroma-blend |
FWIW: It's funny that blending is part of the WC3 Spec (CSS does this blending), but do it in JS you need to re-implement blending. I wonder if there's any way to do color blending in JS without one of those libraries... Maybe draw pixels on a Canvas and read the result or something. |
The typical way of doing this is bilinear interpolation, which you can certainly do using D3. However, if you’re specifically looking to make a bivariate choropleth, I suggest you use a well-designed color palette rather than creating one yourself. This is linked from the D3 bivariate choropleth example: https://www.joshuastevens.net/cartography/make-a-bivariate-choropleth-map/ |
How might one approach bilinear interpolation using D3? This is the closest I could find, which implements the interpolation outside D3: https://observablehq.com/@sw1227/bilinear-interpolation-of-tile Also I'm curious, how might one generalize the approach to more than two variables, for a multivariate choropleth map? I'm investigating how one might approximate the colors of a dot density map, like this one, using multiple single-hue color ramps. Blending the RGBA colors is what came to mind, but perhaps there's a notion of "multilinear interpolation" or something like that. Related:
|
const i1 = d3.interpolateLab(color1, color2);
const i2 = d3.interpolateLab(color3, color4);
const i3 = d3.interpolateLab(i1(t1), i2(t1));
return i3(t2); |
I assume This works for an even number of colors, but what about an odd number like 3 or 5? const color1Scale = scaleLinear()
.domain([0, max(data, color1Value(d))])
.range(['rgba(85, 255, 0, 0)', 'rgba(85, 255, 0, 0)']);
...
const color1 = color1Scale(color1Value(d)); // White
const color2 = color2Scale(color2Value(d)); // Black
const color3 = color3Scale(color3Value(d)); // Asian
const color4 = color4Scale(color4Value(d)); // Hispanic
const color5 = color5Scale(color5Value(d)); // Other
const t1 = 0.5;
const t2 = 0.5; // Maybe this could be tweaked to get the right balance?
const i1 = d3.interpolateLab(color1, color2);
const i2 = d3.interpolateLab(color3, color4);
const i3 = d3.interpolateLab(i1(t1), i2(t1));
const i4 = d3.interpolateLab(i3(t2), color5); // Valid? Too much weight for color5?
return i4(t2); |
You’re describing a multivariate color scheme, not a bivariate one. |
Whow, many thanks for all the inputs! The easy way would be to use a 3x3 matrix and then interpolate between the 9 colors, right as Mike suggested? I'll give that a try. And yes, of course it would be nice to have this also for > 2 variables = multivariate. |
We generated a chromatic color scheme for one of the palettes of Joshua Stevens ( This is what we meant. |
We were discussing whether for map visualization it really makes sense to actually used the chromatic scheme. Would a 10x10 matrix (as an improvement of the 3x3 matrix, which is definitely too scarce in variation) suffice? Any opinions on that? IMHO the main advantage of using the chromatic scheme is to get the precise best matching color for a value t, but for humans probably the difference is not visible :). Colorbrewer supports up to 9 classes for one variable. This generator here up to 6 classes: Any opinions on that? |
Opinions on this vary wildly. Some argue that because the eye can't really differentiate between more than 12 or so distinct colors, one should not use more than that. Others (myself include) argue that ideally you'd use a continuous color ramp (which could be approximated with more classes, maybe 100 classes or so), because the eye is really good at picking up on subtle color differences when the polygons share a border and there's no stroke in between them. |
Thanks for your opinion, I'll also follow that continuous approach, especially as it has the advantage of not having to classify the data. Thanks for the hint regarding removing the borders, we'll give that a try and let you know...! |
We'd like to calculate the color value on a 2-dimensional matrix with 4 colors:
Is that possible with d3js-scale-chromatic?
It appears all functions provide only one variable t.
Any ideas? :)
Thank you & Best regards,
Johannes
The text was updated successfully, but these errors were encountered: