27

I would like to set the matplotlib colorbar range. Here's what I have so far:

import numpy as np
import matplotlib.pyplot as plt
x = np.arange(20)
y = np.arange(20)
data = x[:-1,None]+y[None,:-1]

fig = plt.gcf()
ax = fig.add_subplot(111)

X,Y = np.meshgrid(x,y)
quadmesh = ax.pcolormesh(X,Y,data)
plt.colorbar(quadmesh)

#RuntimeError: You must first define an image, eg with imshow
#plt.clim(vmin=0,vmax=15)  

#AttributeError: 'AxesSubplot' object has no attribute 'clim'
#ax.clim(vmin=0,vmax=15) 

#AttributeError: 'AxesSubplot' object has no attribute 'set_clim'
#ax.set_clim(vmin=0,vmax=15) 

plt.show()

How do I set the colorbar limits here?

3 Answers 3

40

Arg. It's always the last thing you try:

quadmesh.set_clim(vmin=0, vmax=15)

works.

Sign up to request clarification or add additional context in comments.

9 Comments

I would really like to gain a deeper understanding into how this API actually works. If anyone can explain to me why ax.set_xlim works but ax.set_clim doesn't work from an API standpoint, I'd love to hear (and I'm sure others can come up with much better answers than this -- So please explain more if you can!)
I'm not sure if this answers your question, but if you look at quadmesh.__class__.mro() you'll see the quadmesh's class has the ScalarMappable mixin. If you look in matplotlib/cm.py, you'll see it is the ScalarMappable mixin which handles colormapping, and in particular, it provides the set_clim method.
Each (ScalarMappable) artist controls its own color. The colorbar is attached to one ScalarMappable (by the plt.colorbar(quadmesh) call). So the artist's colormapping controls the colorbar's colormapping. It is not an Axes-wide colormapping. Thus, ax has not attribute set_clim.
Also look at what plt.clim does which is to call gci (which gets the current 'image') and calls set_clim on the result. There is a plt.sci() function which lets you set the current image so plt.clim will work. I suspect this didn't get done because you made your pcolor call through the OO interface on the pyplot interface.
Thanks. I was looking for this solution. I learned that you can also just do ax.pcolormesh(X, Y, data, vmin=0, vmax=15).
|
4

Matplotlib 1.3.1 - It looks like the colorbar ticks are only drawn when the colorbar is instanced. Changing the colorbar limits (set_clim) does not cause the ticks to be re-drawn.

The solution I found was to re-instance the colorbar in the same axes entry as the original colorbar. In this case, axes[1] was the original colorbar. Added a new instance of the colorbar with this designated with the cax= (child axes) kwarg.

           # Reset the Z-axis limits
           print "resetting Z-axis plot limits", self.zmin, self.zmax
           self.cbar = self.fig.colorbar(CS1, cax=self.fig.axes[1]) # added
           self.cbar.set_clim(self.zmin, self.zmax)
           self.cbar.draw_all()

Comments

4

[Sorry, actually a comment to The Red Gator in Virginias answer, but do not have enough reputation to comment]

I was stuck on updating the colorbar of an imshow object after it was drawn and the data changed with imshowobj.set_data(). Using cbarobj.set_clim() indeed updates the colors, but not the ticks or range of the colorbar. Instead, you have to use imshowobj.set_clim() which will update the image and colorbar correctly.

data = np.cumsum(np.ones((10,15)),0)
imshowobj = plt.imshow(data)
cbarobj = plt.colorbar(imshowobj) #adjusts scale to value range, looks OK
# change the data to some data with different value range:
imshowobj.set_data(data/10) #scale is wrong now, shows only dark color
# update colorbar correctly using imshowobj not cbarobj:
#cbarobj.set_clim(0,1) #! image colors will update, but cbar ticks not
imshowobj.set_clim(0,1) #correct

3 Comments

@Idoyle Could you explain why you used set_data with division?
@CloudCho oh I hardly remember today... I suppose I wanted to demonstrate the effect of changing the scale afterwards: 1. set some initial data, 2. change the data (in this case 1/10 of the original values) -> result will look wrong/not use full scale, 3. update colorscale -> looks good again. Hope this helps
I was using set_data as above, but my result differed: the display of the data was NOT being affected, instead it displayed as if clim correctly matched the colorbar. The only thing that visibly appeared wrong was the tick labels. According to those wrong tick labels, the display of the data should have been totally obscured, but instead it was exactly correct at all times. Thus, all I had to do to fix the tick labels was set_clim(). Since the display had been correct, I wondered if using set_clim() would then break the display of the data, but it did not. If just fixed the tick labels.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.