Skip to content

Turbo color map #15091

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

Closed
jasongrout opened this issue Aug 20, 2019 · 24 comments
Closed

Turbo color map #15091

jasongrout opened this issue Aug 20, 2019 · 24 comments

Comments

@jasongrout
Copy link

https://ai.googleblog.com/2019/08/turbo-improved-rainbow-colormap-for.html details a new color map that tries to capture some of the detail you get from jet while mitigating some of the perceptual problems.

Looks like the python implementation is licensed Apache 2.0 with Google as the copyright holder: https://gist.github.com/mikhailov-work/ee72ba4191942acecc03fe6da94fc73f

Perhaps this or some similar map would be interesting to include?

There were also a few comments on gitter about this.

@anntzer
Copy link
Contributor

anntzer commented Aug 20, 2019

See #14668 for discussion about shipping new colormaps.

@jklymak
Copy link
Member

jklymak commented Aug 20, 2019

I don't think that discussion said we'd never ship another colormap, just that there should be a strong argument as to why a colormap is worth including in the core library.

@WeatherGod
Copy link
Member

WeatherGod commented Aug 20, 2019 via email

@tacaswell tacaswell added this to the v3.2.0 milestone Aug 20, 2019
@anntzer
Copy link
Contributor

anntzer commented Aug 20, 2019

I'm not saying we shouldn't include turbo (at first glance it certainly looks nice); I just think it may be a good idea to have some criteria laid out for doing so.

@tacaswell
Copy link
Member

@mikhailov-work in the account that owns that gist, if turbo goes in I would prefer it be via a PR from someone at google, but that is a weak preference.

I agree having a documented threshold is a good idea, @WeatherGod 's suggestion of at least "published" is good (I think the blog post surpasses that threshold). Not sure what else we should consider?

As I just mentioned on the 'rainforest' PR, there is existing public API to register a named color map (see https://matplotlib.org/api/cm_api.html )

My current thinking is in favor of including 'turbo'. It seems to be well reasoned and I suspect that it will get picked up by other tools pretty quickly. Also in favor of waiting for 3.3 (~March 2020) rather than squeezing it in for 3.2 (this month) in case there are any tweaks after the first round of publicity.

@shoyer
Copy link

shoyer commented Aug 20, 2019

I'm also very enthusiastic about this!

I ran turbo through viscm:
turbo-viscm

This highlights some potential room for improvement -- perhaps the perceptual derivative could be a bit smoother?

@mikhailov-work
Copy link
Contributor

I'm happy to submit a PR if that makes things easier :)
Indeed, the map looks a bit freaky through viscm. Perceptual lightness derivative could probably be cleaned up while keeping it pretty, maybe I'll give that a go, and see what impact it has on the general perceptual derivative as a byproduct.
I refrained from going too color-science-heavy in the blog, but basically I attempted to make a rainbow map with the constraint of "some kind of analytic curve through CIECAM02-UCS" but it never looked very good or performed well in the field. So in the end I ended up tuning sRGB curves manually (while keeping an eye on color blind acceptability). It's no surprise then, that the perceptual characteristics are a bit wonky. Maybe now that I've got a result I'm happy with by eye, I can go back and use that as a guide to create something more 'principled' and get the best of both worlds.
If anyone has any suggestions I'm certainly all ears as well!

@zanarmstrong
Copy link

I am also excited about adding turbo to matplotlib.

I spoke at SciPy in 2018 about data viz for analysis, including talking about why rainbow colormaps are a valuable tool for analysis due to their high overall perceptual differentiation.

So, it's great to see this colormap that provides a lot of the value of jet, while mitigating the unnecessary weaknesses.

@1313e
Copy link
Contributor

1313e commented Aug 22, 2019

I'm getting really confused here.
Can somebody tell me why everybody jumps on the turbo hype train, while nothing is really happening with the rainforest colormap (#14668)?

@ImportanceOfBeingErnest
Copy link
Member

ImportanceOfBeingErnest commented Aug 22, 2019

@1313e Not everybody jumps on the turbo. But of course you only see those in favour commenting here. Adding a colormap to matplotlib has always been a cumbersome process. The last colormap ("twilight") that was added took around two years from its initial PR to its release. This is partly due to unclear qualilty standards (and a good portion of hypocrisy in some of the arguments). And I guess until the process of adding colormaps follows an objective criteria catalog, this will not change.

However, an alternative, which was suggested at various places, also in #14668, would be to create a separate package, hosted by the matplotlib organization, that would accept new color(map)s at a higher rate with potentially lower standards. Noone has volonteered to set such package up yet.

@jklymak
Copy link
Member

jklymak commented Aug 22, 2019

The reasoning from my point of view is that jet is a super useful colormap that has seen extremely wide use. I would argue that use has not just been because it was the default of various packages. It works as either sequential or diverging, it has lots of hues so you can tell 0.4 out of 1 from 0.6 out of 1, and it looks good. However it has well known perpetual flaws that make it undesireable for some types of plots. Turbo ameliorates those flaws considerably yet maintains the diverging aspect and a broad range of hues. Hence I think it, or something similar, should be offered as a good jet replacement.

With respect to rainforest, we have five “perceptually uniform” colormaps already so adding another with the same perceptual characteristics and different hues faces a higher bar to acceptance in my opinion. The perceptually uniform colormaps all have the same feel to me, and I think that 90% of the time the sequential data they represent would be better represented as grey (our eyes are really good at greyscale). So I’m not generally in favour of adding more unless one can be shown to be substantially better esthetically than those five.

@shoyer
Copy link

shoyer commented Aug 22, 2019

I agree that "turbo" is especially interesting because solving a problem not addressed by perceptually uniform colormaps.

That said, I would also be interested in adding more perceptually uniform colormaps like "rainforest". Five good colormaps is not very many choices for visualization.

@tacaswell
Copy link
Member

The very short answer is because the idealized version of meritocracy is a lie and programing is fundamentally a human/social activity, but that is getting a bit off topic.

And I guess until the process of adding colormaps follows an objective criteria catalog, this will not change.

I am not convinced that such "objective" criteria for accepting / rejecting color maps exist. viridis, inferno, magma, and plasma are all very different looking color maps that were all trying to maximize the same constraints (perceptually unifrom, colorblind safe). I can think of several levels of applying objective constrains (for luminosity: isolumen, linear and monotonic, linear and diverging, montonic but non-linear, diverging but non-linear, cyclic), but even that ends up subjective because you have to pick a model. At the root, color maps are picking a 1D path through a 3D space and (modulo the fact that we are quantizing colors to 24bits and 256 samples) there are effectively an infinite number of valid color maps for any objective constraint (and again, picking the constraints is a subjective activity).

For any given colormap we will have to make a judgement call if this colormap with this name is worth putting into Matplotlib. Is it a good name? Does it "look nice? Is there an audience for this color map? Is it well thought through / motivated? Does it add something that we are currently lacking? Is it "done"? Will users expect a color map with this name?

In this case, as @jklymak argued, turbo is filling a space that there is a demand for (some people really really like rainbow color maps 🤷‍♀️ if we can give them one that is less bad that seems like a win), there is a long and well written blog post explaining why they made it and the choices the made, and it sounds like there may still be some fine tuning.


and a good portion of hypocrisy in some of the arguments

I'm not sure what hypocrisy you are talking about. Including a colormap is fundamentally a judgement call. As people talk through that judgement in a public forum it is important for people to feel safe "thinking out loud" and if it is a close issue argue both sides at different points even if it is . It is also critical that we assume everyone is working in good faith (or the whole thing falls apart).


I previously suggested that we should make a namespace package for color maps, but at the time I had forgotten about register_cmap. I no longer think we need such a package as it is easy for third-party packages to register their own color maps on import (seabon, cmocean, palettable, and colorcet all do this). Might still be worth looking into an entry-point based plugin system, but I don't think that is worth waiting for.


Given @shoyer and @mikhailov-work 's comments I am going to stand by asking this go in no earlier than 3.3 to give it time to anneal a bit and would appreciate a PR from @mikhailov-work .

@tacaswell tacaswell modified the milestones: v3.2.0, v3.3.0 Aug 22, 2019
@mikhailov-work
Copy link
Contributor

Thanks, giving it 'time to anneal' sounds like a good idea. I'll submit a PR in the next few weeks and it can sit there whenever you're ready :)

@1313e
Copy link
Contributor

1313e commented Aug 26, 2019

With respect to rainforest, we have five “perceptually uniform” colormaps already so adding another with the same perceptual characteristics and different hues faces a higher bar to acceptance in my opinion. The perceptually uniform colormaps all have the same feel to me, and I think that 90% of the time the sequential data they represent would be better represented as grey (our eyes are really good at greyscale). So I’m not generally in favour of adding more unless one can be shown to be substantially better esthetically than those five.

@jklymak The rainforest colormap was made specifically to use as many colors as possible, creating the same effect as jet does (where values are very easily distinguishable from each other), but without all the problems jet comes with.
I basically made it to be the replacement for using jet (the original incarnation of rainforest even used a modified jet), intending for it to live alongside viridis as the standard choice.

@mikhailov-work
Copy link
Contributor

Hi @tacaswell, I think the map discussion has stabilized. I took some attempts at making the lightness derivatives more smooth/linear, but it substantially alters the feel of the map (some for better, some for worse), and so I think those will have to be topics for a future work :)

I have a PR ready but you mentioned before that I should add it to 3.3. I didn't see a branch for that yet, should I just hang on till that's available?

Thanks!

@ImportanceOfBeingErnest
Copy link
Member

I have a PR ready but you mentioned before that I should add it to 3.3. I didn't see a branch for that yet, should I just hang on till that's available?

No, every PR should target the master branch. Developpers will then make sure that it's tagged with "v3.3" (and backported if that branch exists already). Nothing to worry about for you, just create the PR for master once you feel you're ready.

@mikhailov-work
Copy link
Contributor

Ah ok, thank you! Here it is #15275.

@mikhailov-work
Copy link
Contributor

By the way, for posterity, here are the results of my attempt to "linearize" turbo to some degree:
image
(thanks @shoyer for running it through viscm)
The lightness derivative is decently linear, but in the end I doubt it will help address people's concerns about perceptual uniformity (since it would need to be constant, not linear). The perceptual derivative is still pretty wild. It also introduces a 'pinkish-orange' color which I think doesn't fit the spectral ordering well.
Ultimately changing it further will just make a very different map and likely lose the advantages discussed in the post. Perhaps most clearly, the low-high-low lightness profile is the source of both the main strength (higher contrast) and the weakness (slightly less contrast at center 'green' and bw ambiguity). So since changing the broader profile is outside of scope of 'tweaking', I'm just going to call this one done and leave improvements for a future date :)

@ImportanceOfBeingErnest
Copy link
Member

Further discussion on the turbo colormap is found in
https://news.ycombinator.com/item?id=20754364

There is a twitter story by a NASA data visualization pro in
https://twitter.com/jscarto/status/1164190471222116352

Also, a detailed analysis of the colorblind-friedlyness is done by @mpetroff in
https://mpetroff.net/2019/08/discernibility-of-rainbow-colormaps/
concluding in

Thus, while Turbo and Rainbow improve upon some of Jet’s shortcomings, neither is colorblind-friendly.

Finally, a funny quote from one user about why one would use the turbo colormap:

“My ignorant boss keeps insisting on using the jet color map even though it is terrible. I can drop this one in and he won’t notice the difference but it will be somewhat better, even if still problematical in many ways.”

@jklymak
Copy link
Member

jklymak commented Sep 17, 2019

I like @mpetroff 's analysis, because it at least makes clear the advantages of colormaps like jet, even though they have issues for colour-blind folks.

@mikhailov-work
Copy link
Contributor

Indeed, even after the 'scathing review' I had great follow up chats with @mpetroff and Joshua :)

Replacing jet for people who won't let go of jet (for valid or invalid reasons) is ultimately the main purpose of this map, so if that means getting around a grumpy boss then I'm all for it! This is a surprisingly common 'real world' issue :\

@bergkvist
Copy link

By copy-pasting the following snippet into your code you can use cmap='turbo' until it is officially added to matplotlib:

import matplotlib.cm
from matplotlib.colors import ListedColormap
turbo_colormap_data = [[0.18995,0.07176,0.23217],[0.19483,0.08339,0.26149],[0.19956,0.09498,0.29024],[0.20415,0.10652,0.31844],[0.20860,0.11802,0.34607],[0.21291,0.12947,0.37314],[0.21708,0.14087,0.39964],[0.22111,0.15223,0.42558],[0.22500,0.16354,0.45096],[0.22875,0.17481,0.47578],[0.23236,0.18603,0.50004],[0.23582,0.19720,0.52373],[0.23915,0.20833,0.54686],[0.24234,0.21941,0.56942],[0.24539,0.23044,0.59142],[0.24830,0.24143,0.61286],[0.25107,0.25237,0.63374],[0.25369,0.26327,0.65406],[0.25618,0.27412,0.67381],[0.25853,0.28492,0.69300],[0.26074,0.29568,0.71162],[0.26280,0.30639,0.72968],[0.26473,0.31706,0.74718],[0.26652,0.32768,0.76412],[0.26816,0.33825,0.78050],[0.26967,0.34878,0.79631],[0.27103,0.35926,0.81156],[0.27226,0.36970,0.82624],[0.27334,0.38008,0.84037],[0.27429,0.39043,0.85393],[0.27509,0.40072,0.86692],[0.27576,0.41097,0.87936],[0.27628,0.42118,0.89123],[0.27667,0.43134,0.90254],[0.27691,0.44145,0.91328],[0.27701,0.45152,0.92347],[0.27698,0.46153,0.93309],[0.27680,0.47151,0.94214],[0.27648,0.48144,0.95064],[0.27603,0.49132,0.95857],[0.27543,0.50115,0.96594],[0.27469,0.51094,0.97275],[0.27381,0.52069,0.97899],[0.27273,0.53040,0.98461],[0.27106,0.54015,0.98930],[0.26878,0.54995,0.99303],[0.26592,0.55979,0.99583],[0.26252,0.56967,0.99773],[0.25862,0.57958,0.99876],[0.25425,0.58950,0.99896],[0.24946,0.59943,0.99835],[0.24427,0.60937,0.99697],[0.23874,0.61931,0.99485],[0.23288,0.62923,0.99202],[0.22676,0.63913,0.98851],[0.22039,0.64901,0.98436],[0.21382,0.65886,0.97959],[0.20708,0.66866,0.97423],[0.20021,0.67842,0.96833],[0.19326,0.68812,0.96190],[0.18625,0.69775,0.95498],[0.17923,0.70732,0.94761],[0.17223,0.71680,0.93981],[0.16529,0.72620,0.93161],[0.15844,0.73551,0.92305],[0.15173,0.74472,0.91416],[0.14519,0.75381,0.90496],[0.13886,0.76279,0.89550],[0.13278,0.77165,0.88580],[0.12698,0.78037,0.87590],[0.12151,0.78896,0.86581],[0.11639,0.79740,0.85559],[0.11167,0.80569,0.84525],[0.10738,0.81381,0.83484],[0.10357,0.82177,0.82437],[0.10026,0.82955,0.81389],[0.09750,0.83714,0.80342],[0.09532,0.84455,0.79299],[0.09377,0.85175,0.78264],[0.09287,0.85875,0.77240],[0.09267,0.86554,0.76230],[0.09320,0.87211,0.75237],[0.09451,0.87844,0.74265],[0.09662,0.88454,0.73316],[0.09958,0.89040,0.72393],[0.10342,0.89600,0.71500],[0.10815,0.90142,0.70599],[0.11374,0.90673,0.69651],[0.12014,0.91193,0.68660],[0.12733,0.91701,0.67627],[0.13526,0.92197,0.66556],[0.14391,0.92680,0.65448],[0.15323,0.93151,0.64308],[0.16319,0.93609,0.63137],[0.17377,0.94053,0.61938],[0.18491,0.94484,0.60713],[0.19659,0.94901,0.59466],[0.20877,0.95304,0.58199],[0.22142,0.95692,0.56914],[0.23449,0.96065,0.55614],[0.24797,0.96423,0.54303],[0.26180,0.96765,0.52981],[0.27597,0.97092,0.51653],[0.29042,0.97403,0.50321],[0.30513,0.97697,0.48987],[0.32006,0.97974,0.47654],[0.33517,0.98234,0.46325],[0.35043,0.98477,0.45002],[0.36581,0.98702,0.43688],[0.38127,0.98909,0.42386],[0.39678,0.99098,0.41098],[0.41229,0.99268,0.39826],[0.42778,0.99419,0.38575],[0.44321,0.99551,0.37345],[0.45854,0.99663,0.36140],[0.47375,0.99755,0.34963],[0.48879,0.99828,0.33816],[0.50362,0.99879,0.32701],[0.51822,0.99910,0.31622],[0.53255,0.99919,0.30581],[0.54658,0.99907,0.29581],[0.56026,0.99873,0.28623],[0.57357,0.99817,0.27712],[0.58646,0.99739,0.26849],[0.59891,0.99638,0.26038],[0.61088,0.99514,0.25280],[0.62233,0.99366,0.24579],[0.63323,0.99195,0.23937],[0.64362,0.98999,0.23356],[0.65394,0.98775,0.22835],[0.66428,0.98524,0.22370],[0.67462,0.98246,0.21960],[0.68494,0.97941,0.21602],[0.69525,0.97610,0.21294],[0.70553,0.97255,0.21032],[0.71577,0.96875,0.20815],[0.72596,0.96470,0.20640],[0.73610,0.96043,0.20504],[0.74617,0.95593,0.20406],[0.75617,0.95121,0.20343],[0.76608,0.94627,0.20311],[0.77591,0.94113,0.20310],[0.78563,0.93579,0.20336],[0.79524,0.93025,0.20386],[0.80473,0.92452,0.20459],[0.81410,0.91861,0.20552],[0.82333,0.91253,0.20663],[0.83241,0.90627,0.20788],[0.84133,0.89986,0.20926],[0.85010,0.89328,0.21074],[0.85868,0.88655,0.21230],[0.86709,0.87968,0.21391],[0.87530,0.87267,0.21555],[0.88331,0.86553,0.21719],[0.89112,0.85826,0.21880],[0.89870,0.85087,0.22038],[0.90605,0.84337,0.22188],[0.91317,0.83576,0.22328],[0.92004,0.82806,0.22456],[0.92666,0.82025,0.22570],[0.93301,0.81236,0.22667],[0.93909,0.80439,0.22744],[0.94489,0.79634,0.22800],[0.95039,0.78823,0.22831],[0.95560,0.78005,0.22836],[0.96049,0.77181,0.22811],[0.96507,0.76352,0.22754],[0.96931,0.75519,0.22663],[0.97323,0.74682,0.22536],[0.97679,0.73842,0.22369],[0.98000,0.73000,0.22161],[0.98289,0.72140,0.21918],[0.98549,0.71250,0.21650],[0.98781,0.70330,0.21358],[0.98986,0.69382,0.21043],[0.99163,0.68408,0.20706],[0.99314,0.67408,0.20348],[0.99438,0.66386,0.19971],[0.99535,0.65341,0.19577],[0.99607,0.64277,0.19165],[0.99654,0.63193,0.18738],[0.99675,0.62093,0.18297],[0.99672,0.60977,0.17842],[0.99644,0.59846,0.17376],[0.99593,0.58703,0.16899],[0.99517,0.57549,0.16412],[0.99419,0.56386,0.15918],[0.99297,0.55214,0.15417],[0.99153,0.54036,0.14910],[0.98987,0.52854,0.14398],[0.98799,0.51667,0.13883],[0.98590,0.50479,0.13367],[0.98360,0.49291,0.12849],[0.98108,0.48104,0.12332],[0.97837,0.46920,0.11817],[0.97545,0.45740,0.11305],[0.97234,0.44565,0.10797],[0.96904,0.43399,0.10294],[0.96555,0.42241,0.09798],[0.96187,0.41093,0.09310],[0.95801,0.39958,0.08831],[0.95398,0.38836,0.08362],[0.94977,0.37729,0.07905],[0.94538,0.36638,0.07461],[0.94084,0.35566,0.07031],[0.93612,0.34513,0.06616],[0.93125,0.33482,0.06218],[0.92623,0.32473,0.05837],[0.92105,0.31489,0.05475],[0.91572,0.30530,0.05134],[0.91024,0.29599,0.04814],[0.90463,0.28696,0.04516],[0.89888,0.27824,0.04243],[0.89298,0.26981,0.03993],[0.88691,0.26152,0.03753],[0.88066,0.25334,0.03521],[0.87422,0.24526,0.03297],[0.86760,0.23730,0.03082],[0.86079,0.22945,0.02875],[0.85380,0.22170,0.02677],[0.84662,0.21407,0.02487],[0.83926,0.20654,0.02305],[0.83172,0.19912,0.02131],[0.82399,0.19182,0.01966],[0.81608,0.18462,0.01809],[0.80799,0.17753,0.01660],[0.79971,0.17055,0.01520],[0.79125,0.16368,0.01387],[0.78260,0.15693,0.01264],[0.77377,0.15028,0.01148],[0.76476,0.14374,0.01041],[0.75556,0.13731,0.00942],[0.74617,0.13098,0.00851],[0.73661,0.12477,0.00769],[0.72686,0.11867,0.00695],[0.71692,0.11268,0.00629],[0.70680,0.10680,0.00571],[0.69650,0.10102,0.00522],[0.68602,0.09536,0.00481],[0.67535,0.08980,0.00449],[0.66449,0.08436,0.00424],[0.65345,0.07902,0.00408],[0.64223,0.07380,0.00401],[0.63082,0.06868,0.00401],[0.61923,0.06367,0.00410],[0.60746,0.05878,0.00427],[0.59550,0.05399,0.00453],[0.58336,0.04931,0.00486],[0.57103,0.04474,0.00529],[0.55852,0.04028,0.00579],[0.54583,0.03593,0.00638],[0.53295,0.03169,0.00705],[0.51989,0.02756,0.00780],[0.50664,0.02354,0.00863],[0.49321,0.01963,0.00955],[0.47960,0.01583,0.01055]]
matplotlib.cm.register_cmap('turbo', cmap=ListedColormap(turbo_colormap_data))

I copy-pasted the turbo_colormap_data from the original gist by Anton Mikhailov.

@QuLogic
Copy link
Member

QuLogic commented Apr 30, 2020

Added in #15275.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests