I've placed a color bar alongside a choropleth map. Because the data being plotted are discrete rather than continuous values, I've used a LinearSegmentedColormap (using the recipe from the scipy cookbook), which I've initialised with my max counted value + 1, in order to show a colour for 0. However, I now have two problems:

The tick labels are incorrectly spaced (except for 5, more or less) – they should be located in the middle of the colour they identify; i.e. 0 - 4 should be moved up, and 6 - 10 should be moved down.
If I initialise the colorbar with drawedges=True, so that I can style its dividers properties, I get this:

I'm creating my colormap and colorbar like so:
cbmin, cbmax = min(counts), max(counts)
# this normalises the counts to a 0,1 interval
counts /= np.max(np.abs(counts), axis=0)
# density is a discrete number, so we have to use a discrete color ramp/bar
cm = cmap_discretize(plt.get_cmap('YlGnBu'), int(cbmax) + 1)
mappable = plt.cm.ScalarMappable(cmap=cm)
mappable.set_array(counts)
# set min and max values for the colour bar ticks
mappable.set_clim(cbmin, cbmax)
pc = PatchCollection(patches, match_original=True)
# impose our colour map onto the patch collection
pc.set_facecolor(cm(counts))
ax.add_collection(pc,)
cb = plt.colorbar(mappable, drawedges=True)
So I'm wondering whether my converting the counts to a 0,1 interval is one of the problems.
Having tried what Hooked suggested, the 0-value is correct, but subsequent values are set progressively higher, to the the point where 9 is where 10 should be:

Here's the code I used:
cb = plt.colorbar(mappable)
labels = np.arange(0, int(cbmax) + 1, 1)
loc = labels + .5
cb.set_ticks(loc)
cb.set_ticklabels(labels)
And just to confirm, labels definitely has the correct values:
In [3]: np.arange(0, int(cbmax) + 1, 1)
Out[3]: array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10])
                Display the data as an image, i.e., on a 2D regular raster. Make a colorbar using colorbar() method with an image scalar mappable object. Set the ticks and tick labels of the colorbar using set_ticks() and set_ticklabels() methods. To display the figure, use show() method.
norm = normi; #mpl. colors. Normalize(vmin=-80, vmax=20); plt. axis([1, 1000, -400, 400]);
Method 2: Change and Rotate the position of the label To rotate the colorbar labels we will use set_xticklabels() and set_yticklabels() methods for horizontal and vertical.
You are suffering from an off-by-one error. You have 10 ticklabels spread among 11 colors. You might be able to correct the error by using np.linspace instead of np.arange. Using np.linspace the third argument is the number of values desired. This reduces the amount of mental gymnastics needed to avoid the off-by-one error:
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.cm as cm
import matplotlib.colors as mcolors
def colorbar_index(ncolors, cmap):
    cmap = cmap_discretize(cmap, ncolors)
    mappable = cm.ScalarMappable(cmap=cmap)
    mappable.set_array([])
    mappable.set_clim(-0.5, ncolors+0.5)
    colorbar = plt.colorbar(mappable)
    colorbar.set_ticks(np.linspace(0, ncolors, ncolors))
    colorbar.set_ticklabels(range(ncolors))
def cmap_discretize(cmap, N):
    """Return a discrete colormap from the continuous colormap cmap.
        cmap: colormap instance, eg. cm.jet. 
        N: number of colors.
    Example
        x = resize(arange(100), (5,100))
        djet = cmap_discretize(cm.jet, 5)
        imshow(x, cmap=djet)
    """
    if type(cmap) == str:
        cmap = plt.get_cmap(cmap)
    colors_i = np.concatenate((np.linspace(0, 1., N), (0.,0.,0.,0.)))
    colors_rgba = cmap(colors_i)
    indices = np.linspace(0, 1., N+1)
    cdict = {}
    for ki,key in enumerate(('red','green','blue')):
        cdict[key] = [ (indices[i], colors_rgba[i-1,ki], colors_rgba[i,ki])
                       for i in xrange(N+1) ]
    # Return colormap object.
    return mcolors.LinearSegmentedColormap(cmap.name + "_%d"%N, cdict, 1024)
fig, ax = plt.subplots()
A = np.random.random((10,10))*10
cmap = plt.get_cmap('YlGnBu')
ax.imshow(A, interpolation='nearest', cmap=cmap)
colorbar_index(ncolors=11, cmap=cmap)    
plt.show()

You can control the placement and the labels by hand. I'll start with a linear cmap generated from cmap_discretize on the page you linked:
import numpy as np
import pylab as plt
# The number of divisions of the cmap we have
k = 10
# Random test data
A = np.random.random((10,10))*k
c = cmap_discretize('jet', k)
# First show without
plt.subplot(121)
plt.imshow(A,interpolation='nearest',cmap=c)
plt.colorbar()
# Now label properly
plt.subplot(122)
plt.imshow(A,interpolation='nearest',cmap=c)
cb = plt.colorbar()
labels = np.arange(0,k,1)
loc    = labels + .5
cb.set_ticks(loc)
cb.set_ticklabels(labels)
plt.show()

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With