I am trying to use a colorbar to label discrete, coded values plotted using imshow. I can achieve the colorbar that I want using the boundaries
and values
keywords, which makes the maximum value of the colorbar effectively 1 greater than the maximum value of the data being plotted.
Now I want ticks to be in the middle of each color range in the colorbar, but cannot specify a tick position for the largest color block in the colorbar, seemingly because it is outside of the data value limits.
Here's a quick block of code to demonstrate the problem:
data = np.tile(np.arange(4), 2)
fig = plt.figure()
ax = fig.add_subplot(121)
ax.imshow(data[None], aspect='auto')
cax = fig.add_subplot(122)
cbar = fig.colorbar(ax.images[0], cax=cax, boundaries=[0,1,2,3,4], values=[0,1,2,3])
cbar.set_ticks([.5, 1.5, 2.5, 3.5])
cbar.set_ticklabels(['one', 'two', 'three', 'four'])
Note the missing tick where 'four' should be. What's the right way to do this?
To summarize, this works for me:
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import cm
from matplotlib import colors
data = np.tile(np.arange(4), 2)
fig = plt.figure()
ax = fig.add_subplot(121)
cmap = cm.get_cmap('jet', 4)
bounds = np.arange(5)
vals = bounds[:-1]
norm = colors.BoundaryNorm(bounds, cmap.N)
ax.imshow(data[None], aspect='auto', interpolation='nearest', cmap=cmap, norm=norm)
cax = fig.add_subplot(122)
cbar = fig.colorbar(ax.images[0], cax=cax, boundaries=bounds, values=vals)
cbar.set_ticks(vals + .5)
cbar.set_ticklabels(['one', 'two', 'three', 'four'])
The solution was to specify the colormap explicitly for the image using get_cmap
and bounded by BoundaryNorm
. Then specifying the tick positions just works. The resulting plot is:
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