Skip to content

[Wishlist/candidate for gallery?] Diverging colormap taking into account asymmetry of the data about vcenter #12449

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
pharshalp opened this issue Oct 8, 2018 · 5 comments
Labels
Documentation status: closed as inactive Issues closed by the "Stale" Github Action. Please comment on any you think should still be open. status: inactive Marked by the “Stale” Github Action

Comments

@pharshalp
Copy link
Contributor

pharshalp commented Oct 8, 2018

I have been using a different approach to achieve what #12419 tries to address (DivergingNorm).
The limitation of using something like DivergingNorm is that it doesn't allow for using color range proportional to the extent of the vmax, vmin w.r.t. vcenter (please see the example below). I have been using the following hackish approach to get over this limitation. This approach also allows for using colorbar extensions with the ability to specify different colors for data > vmax and/or data < vmin [based on my understanding, this won't be possible if DivergingNorm is used].

Would this be a useful addition to the gallery? Does it look like a functionality that I should think of adding to Matplotlib? (Also, please let me know if there is an easier way of achieving the same result).

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import copy

def div_proportional_colormap(cmap='coolwarm', vmin=-1., vmax=1.,
                              vcenter=0., cmap_name='my_cmap'):
    """ Given a diverging colormap, this returns a diverging
        colormap with color ranges on either side proportional to
        the extent of vmax, vmin w.r.t. vcenter i.e. vmax-vcenter, vcenter-vmin
    """
    if isinstance(cmap, str):
	    cmap = cm.get_cmap(cmap)

    max_delta_v= max(vcenter-vmin, vmax-vcenter)
    cmap_min = 0.5-0.5*(vcenter-vmin)/max_delta_v
    cmap_max = 0.5+0.5*(vmax-vcenter)/max_delta_v
    my_colors = cmap(np.linspace(cmap_min, cmap_max, 512))
    my_cmap = mcolors.LinearSegmentedColormap.from_list(cmap_name, my_colors)
    return my_cmap

x = np.linspace(-2, 7)
y = np.linspace(-1*np.pi, np.pi)
X, Y = np.meshgrid(x, y)
Z = x * np.sin(Y)**2

fig, (ax1, ax2) = plt.subplots(ncols=2)
my_cmap1 = div_proportional_colormap(cmap=plt.cm.coolwarm,
                                     vmin=-2., vmax=6., vcenter=0.,
                                     cmap_name='my_cmap1')
my_cmap2 = copy.copy(my_cmap1)
my_cmap2.set_over('orange')

img1 = ax1.pcolormesh(Z, cmap=my_cmap1, vmin=-2, vmax=6)
cbar1 = fig.colorbar(img1, ax=ax1)

img2 = ax2.pcolormesh(Z, cmap=my_cmap2, vmin=-2, vmax=6)
cbar2 = fig.colorbar(img2, ax=ax2, extend='max')
plt.show()

figure_1

@jklymak
Copy link
Member

jklymak commented Oct 8, 2018

I’m pretty sure there is an example like this in the new making colormaps tutorial (see the dev docs).

I’m not following the issue with extended data. Does divergingmorm not work w that feature? If true I’m sure that can be fixed

@pharshalp
Copy link
Contributor Author

I’m pretty sure there is an example like this in the new making colormaps tutorial (see the dev docs).

Thanks! I will take a look. By dev docs you mean the ones generated by CircleCI right?

I’m not following the issue with extended data. Does divergingmorm not work w that feature? If true I’m sure that can be fixed

please see the following example which uses the divergingnorm and fails to show the expected results.

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors

x = np.linspace(-2, 7)
y = np.linspace(-1*np.pi, np.pi)
X, Y = np.meshgrid(x, y)
Z = x * np.sin(Y)**2

fig, (ax1, ax2) = plt.subplots(ncols=2)
cmap = plt.cm.coolwarm
norm = mcolors.DivergingNorm(vmin=-2, vcenter=0, vmax=6)

img1 = ax1.pcolormesh(Z, cmap=cmap, norm=None)
cbar1 = fig.colorbar(img1, ax=ax1, extend='neither')

cmap.set_over('orange')
img2 = ax2.pcolormesh(Z, cmap=cmap, norm=norm, vmin=-2, vmax=6)
cbar2 = fig.colorbar(img2, ax=ax2, extend='max')

plt.show()

figure_2

@jklymak
Copy link
Member

jklymak commented Oct 8, 2018

Ok we can work on over under support for diverging norm.

Dev docs are linked on the front page of the main docs

@github-actions
Copy link

This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!

@github-actions github-actions bot added the status: inactive Marked by the “Stale” Github Action label May 18, 2023
@github-actions github-actions bot added the status: closed as inactive Issues closed by the "Stale" Github Action. Please comment on any you think should still be open. label Jun 19, 2023
@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Jun 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Documentation status: closed as inactive Issues closed by the "Stale" Github Action. Please comment on any you think should still be open. status: inactive Marked by the “Stale” Github Action
Projects
None yet
Development

No branches or pull requests

3 participants