-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
fire/ice blue/yellow bipolar colormap #6033
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
Comments
The top-image is playing tricks with my eyes. I could really use it, i use 'bwr' all the time and wouldnt mind a little bit more color dynamic. (Time-resolved difference spectroscopy) |
I am tentatively 👍 on including the black center and white center version over a single generation function. The pros of just including the maps is that the cognitive load for users is low, but the con is low flexibilty. The pro of adding the function is high flexibility, but also very high cognitive load / low discoverability. If you have a nice function to generate these maps, it might be better to integrate that into viscm (@njsmith @stefanv) How do these colormap fare under the in luminosity linearity / color blind metrics? For reference, these are the diverging color maps we currently ship: |
This is just designed by picking solve corners of the RGB cube and interpolating between them, which is not a design method that I'm particularly fond of -- but matplotlib has all kinds of more or less well designed colormaps in it so I'm not sure what the bar is. It would certainly make sense to at least stick it through |
Well, if it were included as a function, it would be similar to the existing cubehelix function. Generates a fixed map out of the box, but can be accessed as a function if someone wants to generate a variation. ... Though now that I look at it, cubehelix isn't as easy to use as I expected. I thought you could do
Yep. But cyan and yellow are similar in perceptual lightness so it works pretty well. Here it is in Lab/Lch space: Here's what happens in RGB space when the midpoint is changed: Ideally matplotlib would have colorspace conversion abilities built-in and then we could do maps like this and color_scale as functions. |
@endolith Maybe use viscm to flatten out the perceptual deltas? I really want to see a better set of colormaps like this made readily available for mpl--which might be by direct inclusion, or via an import-- but I don't want it to hold up 2.0, so I am moving the goalpost. |
FYI https://github.com/bokeh/colorcet provides 3 perceptually-smooth bipolar black-center maps now:
|
Is anything in the license preventing us from bringing them into Matplotlib? |
License is CC-BY-4.0, and BSD does not require attribution? So I'm not sure. https://opensource.stackexchange.com/a/344/9996 |
Thanks for the viz! As always the plots I like the most are the ones least-perceptually-flat haha re: Licenses, I think that we should be fine as long as we include that license here: https://github.com/matplotlib/matplotlib/tree/master/LICENSE does that sound correct @tacaswell ? Licenses are still mysterious to me... |
That is not true; BSD requires reproducing both the copyright notice and the license. |
Ah so we need to include the "Anaconda" copyright language in matplotlib somewhere, as well as the license. That it? |
Yes, the licences files go in https://github.com/matplotlib/matplotlib/tree/master/LICENSE and the source needs to be noted is the whats_new, in any docstrings, and a comment where they are defined. |
Also found https://github.com/bastibe/twilight and figured out how to use bezier RGB bipolar: viscm bipolar: At high lightness I can get it to hug the chroma wall, since hue is changing: but the way viscm's curve works, I can't get it to do the same at low lightness, since the hue is constant, so it descends into the low chroma gray muck in the middle: In other words, there are multiple curves in 3D that have the same 2D top-down projection, but viscm only lets you adjust the 2D projection? |
That's correct: given a 2D top-down projection there is only 1 possible 3D curve, if you add the constraint that you want the colormap to remain perceptually uniform when translated into greyscale, which viscm does. Of course you might say, well, who cares about printing in greyscale, here we're designing a diverging map with a V-shaped lightness curve, so anyone printing in greyscale is screwed anyway. And there's some truth to that. But you still should care about lightness uniformity at least a little, since it turns out that even when viewing images in color, people mostly attend to the lightness component, and ignore the hue/saturation – and crucially, this effect is not fully accounted for by the models we use to estimate perceptual uniformity. (Technically, IIRC, the issue is that the visual system is becomes relatively more sensitive to lightness and less sensitive to hue/saturation at higher spatial frequencies, and perceptual delta models like CAM02-UCS and CIELAB are all calibrated to match human performance on super-low spatial frequencies. And most data varies over space, that's why we need a colormap :-).) By making the colormap perceptually uniform in hue/saturation and perceptually uniform in lightness separately, we get a colormap that remains perceptually uniform at all spatial frequencies. At least in theory. In practice, small deviations from perceptual uniformity are probably not that big a deal, and all these models are approximations anyway, so it's not clear how much we should really care about these details. |
What I mean is that you can have multiple 3D curves that are identical when projected to 2D from above, and have the same lightness uniformity (the same linearly-spaced lightness along the black-to-white Z axis), but differ in how far out they go in the chroma radius. Instead of being at the yellow dot, I want it to be closer to the green dot (while maintaining the same lightness and hue): Obviously it's hard to describe 3D space curves in text, but you can see plots of color that hugs the RGB wall here, with two different philosophies: https://github.com/endolith/complex_colormap The low-lightness regions still have high chroma, they don't become gray. The constant-chroma version follows this curve of chroma vs lightness: https://flic.kr/p/24QbbJG but around lightness of 30, the curve created by viscm is lower in chroma than it could be, because I can't describe the curve's shape in 3D, only 2D projection. |
I don't understand what you mean. The chroma radius is the radius axis in the "2D from above" projection, so if they're identical when projected to 2D from above, then they're also identical in how far out they go in the chroma radius, by definition. The "2D from above" project determines which (hue, chroma) values the curve passes through, but not when it does so – you can stretch or squish how it maps onto the [0, 1] data span. But if you uniform lightness spacing, and you want the final curve to be perceptually uniform in 3d space, then it implies that the points along the 2d curve also have to be uniformly spaced. BTW, from
CIECAM02 JCh is not a perceptually uniform color space. |
I've been having a lot of trouble trying to generate the curves programmatically, so I'll draw a picture :) Here is the view from above, in Jab/JCh space, with a path going from black (0,0,0) to blue (RGB 0,0,1 = JCh 21, 90, 258°), in a linear fashion, so that hue does not change, but lightness and chroma do change: The dotted line is the plane along which this next graph is a cross-section: Here you can see that there are actually 3 different curves, which all look the same from above. They are all sampled linearly along the J axis (black dots), so when converted to grayscale, they are all identical. However, they differ in the amount of chroma they have at each point in the curve.
Oh! I must have misunderstood something. Which cylindrical coordinate colorspace is perceptually uniform? I had noticed that the lightness didn't seem linearly increasing, but I assumed it was from being displayed on an LCD vs the ideal illuminant scenario, etc. |
Hey all - this is a super interesting conversation, though can we get a quick check-in on the actionable points for this issue so it doesn't get lost? It sounds like somebody could:
Does that sound right, or is there anything else? (maybe we could also paste a list such as this in the top-level comment so it's clear how we can close this issue if somebody wants to take it on :-) ) |
@choldgraf Well I'm in the process of trying to re-design a color map similar to my original comment, except starting in a perceptually uniform space, as per comments #6033 (comment) and #6033 (comment) (The grayscale map is not symmetrical, for instance.) Whether to include colorcet/twilight/etc maps can be a separate Issue?
I see now that viscm uses J'/K as the vertical axis, not J, so my "linear on J" attempts are not linear in viscm. Is that what you mean? |
Pretty sure twilight was merged already. |
twilight was merged in #6254, and I think we should really think about #6254 (comment) before adding any new colormaps, regardless of their merits. Copied here (from @njsmith):
|
@endolith Oh, I see. A background assumption I was making was that you want a perceptually uniform colormap, which means that in your final 3d curve all the points are equally spaced. Your "g" and "m" plots don't have this property – the spaces between the dots are quite visibly different at different parts of the curve. Again, you could potentially argue that you don't want to stick strictly to this constraint, but you should at least realize when you aren't :-)
Yeah, the CIECAM02 equivalent to Lab is CAM02-UCS, whose coordinates are J'/K, a', b'. (The authors of that paper did not think these names through.) This is a Cartesian coordinate system. The equivalent of LCh is... "CAM02-UCS, converted to cylindrical coordinates". It doesn't have its own name, but it's just the grade school rectangular/polar conversion. |
Oh, so specifically, you mean the Euclidean distance (in CAM02-UCS space) between each sample is equal?
Ok, that's helpful, I'll try to figure this out. |
Exactly. |
There was some discussion some time ago about making it easier for people to generate their own packages for distributing custom colormaps (this way not everything has to go into matplotlib directly); having just had to write one (for my own use) I put together https://github.com/anntzer/matplotlib-cmap-template. (Yes, I know about cookiecutter and I actually quite like using that myself, but in this specific case I thought the template was just simple enough to not pick up a dependency on a templating system. If there's demand I can still make a cookiecutter for it though...) |
very cool @anntzer , thanks for sharing! |
@anntzer Nice! Two suggestions:
|
Done.
Uh? You mean |
Yes, sorry (auto-type in my fingers...). Ok, let's say +/-0 on |
My proposition is to close this, encourage @endolith to publish the cmap as an independent PyPI package (for example (but not necessarily, of course) relying on the package template mentioned just above), and possibly link it back in the docs. |
I agree w/ this.... plus the new colormap tutorial hopefully makes making custom colormaps easier... https://matplotlib.org/tutorials/colors/colormap-manipulation.html#sphx-glr-tutorials-colors-colormap-manipulation-py |
There are several variations of this theme in existence:
I made one using bezier curves to reduce banding:
It does have a sharp angle at the midpoint causing a black band for 0, but that's intentional because it's for diverging data. (would be best with #1806) Here it is with a wavelet scalogram:
Like Ged Ridgway's, the midpoint brightness can be changed, with gray for surface plots, etc:
and color order flips if midpoint is brighter than gray:
Would this be good for inclusion, either as a (cleaned-up) function or as a single fixed map?
The text was updated successfully, but these errors were encountered: