-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
ColorbarBase fails to show if the first two values map to the same result #11923
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
Any chance you have a less perverse example you could give us? The norm you gave above cares about the order of x, and the norm really shouldn't care about that (i.e. it makes the second element always be the same as the first); you should be doing that sort of thing in the data array before it goes to norm. I assume you've seen the BoundaryNorm. It may be possible your norm doesn't work with colorbar and or you may need to provide a locator and formatter. |
This a (I believe) less contrived example: %matplotlib inline
import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np
plt.close('all')
fig,ax = plt.subplots(1,1)
class MyNorm(mpl.colors.Normalize):
def __call__(self, value, clip=True):
if clip is None:
clip = self.clip
result, is_scalar = self.process_value(value)
result_dat = np.interp(result.data, [0,200, 1000, 12000], [0,0.00, 0.3,1])
result = np.ma.array(result_dat)
return result
norm = MyNorm(vmax=12000, vmin=0, clip=False)
#norm = mpl.colors.Normalize(vmin=0, vmax=12000, clip=True)
cmap = plt.get_cmap('RdYlGn_r') # From red to green
sm = mpl.cm.ScalarMappable(norm=norm, cmap=cmap)
cb1 = mpl.colorbar.ColorbarBase(ax, cmap=cmap, norm=norm, orientation='vertical',
ticks=[100, 1000, 10000])
plt.show() What I'm trying to achieve an effect similar to BoundaryNorm where only certain bands are "solid" the rest are gradients. It kinds of work as long as the band is not in the very beginning (although it messes up the tick locations). EDIT: By the way , I guess you could say for the case of the band on the beginning and end the |
Thanks - in the meantime would changing the colormap to have bands be an alternative solution for you? See #11905 for a description of how to manipulate colormaps... |
A norm needs to have an inverse defined for colorbar to work properly, and you had one, but it was the inverse for Normalize, not the norm you had written, so naturally Secondly, you probably want to define your "y" in your norm with unique numbers, I'm going to close because I don't think there is much we can do from our end with this. import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np
fig,ax = plt.subplots(1,1)
class MyNorm(mpl.colors.Normalize):
def __call__(self, value, clip=True):
if clip is None:
clip = self.clip
result, is_scalar = self.process_value(value)
result_dat = np.interp(result.data, [0,1000, 2000, 12000], [0, 0.0000001, 0.3,1])
print(result_dat)
result = np.ma.array(result_dat)
print(result)
return result
def inverse(self, value):
return np.interp(value, [0, 0.00000001, 0.3,1],[0, 1000, 2000, 12000] )
norm = MyNorm(vmax=12000, vmin=0, clip=False)
#norm = mpl.colors.Normalize(vmin=0, vmax=12000, clip=True)
cmap = plt.get_cmap('RdYlGn_r') # From red to green
sm = ax.pcolormesh(np.random.rand(3, 3)*10000, norm=norm)
cb = fig.colorbar(sm, ax=ax)
plt.show() |
Bug report
When ColorbarBase is used with a custom Normalizer, if the normalizer maps the first two elements of the input to the same output value then it will raise an
ValueError: Both *x_transform* and *y_transform* must be 2D affine transforms
Code for reproduction
Actual outcome
empty figure canvas
If using module://ipykernel.pylab.backend_inline then console show
Expected outcome
A colorbar where the bottom two lines are the same color.
In the actual case where I encountered I have a custom normalizer in which I wanted to map certain ranges of values to a single color (instead of doing a regular gradient). It works fine unless the first two map to the same color. As an example if you replace
fixed_result[1] = fixed_result[0]
withfixed_result[2:200] = fixed_result[1]
it works.Matplotlib version
print(matplotlib.get_backend())
): module://ipympl.backend_nbagg and module://ipykernel.pylab.backend_inlineInstalled via conda official
The text was updated successfully, but these errors were encountered: