WIP: Experimenting with rounding vs truncating RGB values#31134
WIP: Experimenting with rounding vs truncating RGB values#31134ayshih wants to merge 3 commits intomatplotlib:mainfrom
Conversation
|
As a note / side question: Is there a measureable performance difference? Some colormap design decisions in the history have been performance-based since colormaps handle many values. Probably negligable, but worth a thought before going in one direction. |
|
A few additional notes that may be relevant:
I'd say rgb2hex should round rgb values, though I don't have a very strong opinion there. |
Not really: the run times stay within the typical fluctuation range. I've timed Colormap truncatingN = 30 N = 300 N = 3000 Colormap roundingN = 30 N = 300 N = 3000 |
The quantization is done at import-time. You can set a different value via matplotlibrc and then get higher sampling. There is a need for higher sampling(e.g. #22728). However, for ListedColormaps, this only results in linear interploation between the list elements. LinearSegmentedColormaps can by construction be interpolated arbitrarily. But currently do not have a way to sample a colormap from a functional relationship at a requested resolution (e.g. turbo). Colormapping speed should not depend on the size of the LUT. So the only parameter that goes up with the LUT is the memory size. Currently we have 86 colormaps x 3 channels x 8byte (note: the LUT uses float), which results in 0.5MB storage. A factor 2-4 would be bearable for most modern systems, but OTOH we sould stive to keep our footprint low. Deferred colormap creation #30578 could help with that - but only if we don't put all raw data in a single python file. |
|
Ha, whoops, my timing tests of making a single image were silly. They basically just affirm that the one-time cost of generating the uint8 RGB values for the LUT is negligible compared to the rest of the image processing, which scales with image size. I guess the question is whether there's a realistic use case of |
|
Not sure I understand your argument/questions. Instantiating colormaps via Colormap creation is not performance critical, and we still have means to improve that. The question with rounding is about evaluation. And thinking about it, the difference is essentially a shift of 0.5 of the data (or lut), so still cheap. Semi-OT: I noted that colormaps by default evaluate on the float-lut. They only discretize to uint8 if |
|
Sorry, when I wrote One highly unrealistic case is if someone chose to use a gigantic number of |
PR summary
This PR is just for testing for now. Per #20459 (comment), the conversion of RGB values from floats to uint8 is not handled consistently:
rgb2hex()rounds RGB values (this is used by the SVG backend for some artists)Colormap.__call__(..., bytes=True)truncates RGB values (this is used when colorizing data arrays)I want to see how many image-comparison tests break when changing one to match the other.
Update:
The score is:
Colormap.__call__(..., bytes=True)to round RGB values breaks at least 58 testsrgb2hex()to truncate RGB values breaks 12 tests, all SVGFrom a technical perspective, I'd lean toward rounding, but that would mean updating a lot more baseline images than going with truncating. Either way, it might make sense to lump the change into #31021 to avoid updating a bunch of baseline images twice.
PR checklist