-
Notifications
You must be signed in to change notification settings - Fork 29
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
ENH: Add cmasher.combine_cmaps
#122
Conversation
Here I enclose a minimal code snippet to test this function: cmaps = ["Blues", "Oranges", "Greens"]
nodes = [0.2, 0.75]
custom_cmap = combine_cmaps(cmaps, nodes)
# Test plotting with the custom colormaps
x = np.linspace(0, 10, 100)
y = np.sin(x)
# Example plot
fig, ax = plt.subplots()
sc = ax.scatter(x, y, c=x, cmap=custom_cmap, marker='o')
plt.colorbar(sc, ax=ax, label='Sample Data')
plt.show() |
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## dev #122 +/- ##
==========================================
+ Coverage 98.36% 98.52% +0.16%
==========================================
Files 6 6
Lines 611 676 +65
==========================================
+ Hits 601 666 +65
Misses 10 10 ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @DanielYang59, thank you for your work ! This seems like a reasonable addition to the package, but before I can do an in-depth review, please address the following points:
- stylistic changes in unrelated lines should be reverted (let's keep the scope of the PR as narrowly defined as possible). If you wish, please open a separate PR for these.
- there are some type-checking errors, please address them. Let me know if you need a hand with this part.
Thanks !
Actually, and I'm sorry if this sounds distressing, but I need to ask: what's your reasoning for adding this function to cmasher, specifically ? it doesn't seem to rely on existing cmasher functionality, and, as you are well aware it is perfectly fine outside the package. Have you considered contributing this to other matplotlib extension packages ? https://matplotlib.org/mpl-third-party/ |
Thanks a lot for asking here. The reason actually went through only limited mind work... Just me happening to find |
that's reasonable, but I'll ask @1313e to make the final call here :) |
Sure thanks for that. Meanwhile I'm getting another error from
What might be the reason for this? Thanks. |
I suggest to install and run |
pre-commit.ci autofix |
Thanks a ton! Another new trick learned. However I'm getting some trouble with my local SSL module and I'll fix it ASAP. Thanks a lot for your patience! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that CI is all green, here's an in-depth review !
cmasher/utils.py
Outdated
|
||
Note | ||
---- | ||
The colormaps are combined from bottom to top. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure this is helpful: colormaps don't have an absolute orientation, and may be displayed horizontally. Is there a way to rephrase this note that would work independently of orientation ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking the same about the necessity of having the note and the phrasing of the note yesterday.
As the LinearSegmentedColormap.from_list()
function would combine the cmaps from lower value end to higher value end (if not reversed, that is bottom to top). So this is expected behaviour for the cmaps to start from the lower value end. But meanwhile for me, I expected the cmaps to be combined from top to bottom at first attempt, when I don't have much understanding of Colormap
.
Maybe we could remove this note altogether? As the behaviour is expected?
Or rephrase it to something like "The colormaps are combined from low value to high value end."? What would your suggestion be?
Yeah, I think it can have a place in CMasher. |
Thanks for granting the permission 😄! Sure I would work with @neutrinoceros to draft a docs as well. Thanks a ton. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This round of review is mostly about the interface design, as I think it should be converged before you write documentation. Thank you !
cmasher/utils.py
Outdated
cmaps: list[Union[Colormap, str]], | ||
*, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this round of review, I'll make suggestions to change the interface so that positional arguments are used for cmaps instead of a list as the first argument. This is the fundamental change, all following suggestions will be adapting call sites and docs
cmaps: list[Union[Colormap, str]], | |
*, | |
*cmaps: Union[Colormap, str], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I'm not understanding this change well enough here (especially the pros and cons)...
In current implementation, cmaps
would take exactly a list
; while in the suggested implementation, any number of positional args would be recognised as parts of cmaps
and would be zipped during runtime.
From my understanding, the current implementation is "stricter" by explicitly requiring a list
of Colormaps
, and suggested implementation being more flexible ("lighter" as you described).
By making this change (and the other change to make all other args keyword), we are being more flexible by requesting other args to be keyword, leaving only cmaps
positional, am I right?
I feel this should be safe and good as this utility would only take several Colormaps
and combine them, so it's reasonable to expect cmaps
to be the focus here.
For the record, the reason why CI is failing now is that you added an implicit dependency on |
Oh, and I'm just noticing now, but we don't merge on |
I'm glad you're enjoying it ! we're almost there, I think all we need now is documentation as requested by @1313e :) |
More than enjoying this (thanks really a lot for your patience and all these valuable suggestions). Yes actually I had already added a draft section under |
Do you have any advice on the docs @neutrinoceros ? Thanks! |
@DanielYang59 I think a new section in |
Thanks @neutrinoceros. I would see if I could pre-render the rst locally for preview, as I totally have no prior experience with reStructuredText and just followed the grammar of other parts in that docs file 😄 . |
building docs locally should boil down to something like python -m pip install -r requirements/docs.txt
sphinx-build -M html docs/source site -W |
Looks cool ! I think I would make the example use 3 color maps to make it even clearer that this works with any number of them. |
Also, try to pick a set of colormaps that don't have any color in common so the example also illustrates communication best practices. |
Yes this makes sense. In fact I started with two distinct colormaps ("prism" and "Pastel2") but then noticed other parts of the docs use "rainbow" and "lilac" so just tried to be consistent. I would implement the changes now. |
What about now @neutrinoceros ? Update: |
While trying to find a more realistic combination (something that users would actually do), I found that After experimenting with it, I find that, actually, the only examples I can come up with that feel natural to me involve only two colormaps, so I changed my mind. How about |
On the docs: They look great and with neutrinoceros' suggestion, I think it will be perfect. |
Thanks a lot for sharing this background story, that's awesome (
Thanks, this has been rectified 😄 . |
This has been fixed. Thanks for pointing out.
I guess this is really hard decision here. If we use two distinct colormaps (like my case), it might be easier for docs reader to tell one colormap from another, but feels less natural (and looks much less beautiful). On the other hand, if we use two naturally fitting together colormaps, it might be hard to tell the boarder. What about |
rainforest + torch_r looks awesome. And thanks Ellert for sharing, I also didn't know that rainforest was special :) |
Should be good now. Please review @neutrinoceros. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Docs look very good, I just have a couple nitpicks ! While I'm here, is it okay with you if I just squash your branch before I merge ? I don't think we need to keep all original 50 commits
Yes sure, please do that @neutrinoceros . Thanks a lot! |
cmasher.combine_cmaps
Co-authored-by: Clément Robert <[email protected]>
Thanks a lot @neutrinoceros @1313e , enjoyed this process. |
Thank you for going through this with us ! |
I noticed that too: installing twine...
Uploading distributions to https://upload.pypi.org/legacy/
Uploading cmasher-1.8.0-py3-none-any.whl
25l
0% ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 0.0/546.0 kB • --:-- • ?
33% ━━━━━━━━━━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━ 180.2/546.0 kB • 00:01 • 9.5 MB/s
100% ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 546.0/546.0 kB • 00:00 • 8.4 MB/s
100% ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 546.0/546.0 kB • 00:00 • 8.4 MB/s
25hWARNING Error during upload. Retry with the --verbose option for more details.
ERROR HTTPError: 403 Forbidden from https://upload.pypi.org/legacy/
Invalid or non-existent authentication information. See
https://pypi.org/help/#invalid-auth for more information.
Error: Process completed with exit code 1. Take your time though. Thanks for all those suggestions. Learned a lot about details and quality of coding during this PR. |
Overview
Add a custom function to easily combine multiple
matplotlib
colormaps at givenpositions
:EDIT by @neutrinoceros : I've updated the illustrative example to use the final version of the interface for posterity. The original example is still viewable in the following. The only difference is on the last line.
Orignal example
TODO list