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 itsdividers
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.
Update :
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])
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 ofnp.arange
. Usingnp.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: