Matplotlib: misaligned colorbar ticks?
<p>I'm trying to plot data in the range 0-69 with a bespoke colormap. Here is an example:</p>

<pre><code>import matplotlib.pyplot as plt
import numpy as np
from matplotlib.colors import LinearSegmentedColormap

colors = [(0.9, 0.9, 0.9),    # Value = 0
          (0.3, 0.3, 0.3),    # Value = 9
          (1.0, 0.4, 0.4),    # Value = 10
          (0.4, 0.0, 0.0),    # Value = 19
          (0.0, 0.7, 1.0),    # Value = 20
          (0.0, 0.1, 0.3),    # Value = 29
          (1.0, 1.0, 0.4),    # Value = 30
          (0.4, 0.4, 0.0),    # Value = 39
          (1.0, 0.4, 1.0),    # Value = 40
          (0.4, 0.0, 0.4),    # Value = 49
          (0.4, 1.0, 0.4),    # Value = 50
          (0.0, 0.4, 0.0),    # Value = 59
          (1.0, 0.3, 0.0),    # Value = 60
          (1.0, 0.8, 0.6)]    # Value = 69

# Create the values specified above
max_val = 69
values = [n for n in range(max_val + 1) if n % 10 == 0 or n % 10 == 9]

# Create colormap, first normalise values
values = [v / float(max_val) for v in values]
values_and_colors = [(v, c) for v, c in zip(values, colors)]
cmap = LinearSegmentedColormap.from_list('my_cmap', values_and_colors,
                                         N=max_val + 1)

# Create sample data in range 0-69
data = np.round(np.random.random((20, 20)) * max_val)

ax = plt.imshow(data, cmap=cmap, interpolation='nearest')
cb = plt.colorbar(ticks=range(0, max_val, 10))
plt.show()
</code></pre>

<p><a href="http://i.stack.imgur.com/ZROy0.png" rel="nofollow"><img src="http://i.stack.imgur.com/ZROy0.png" alt="enter image description here"></a></p>

<p>I'm thoroughly puzzled as to why the colorbar ticks do not line up with the distinct separations between the color gradients (for which there are 10 colors each).</p>

<p>I've tried setting the data and view intervals from [0, 69] to [0, 70]:</p>

<pre><code>cb.locator.axis.set_view_interval(0, 70)
cb.locator.axis.set_data_interval(0, 70)
cb.update_ticks()
</code></pre>

<p>but this doesn't appear to do anything.</p>

<p>Please can someone advise?</p>

<p>The simplest way to solve my problem was to set <code>vmax</code> in the definition of the mappable:</p>

<pre><code>ax = plt.imshow(data, cmap=cmap, interpolation='nearest', vmax=max_val + 1)
</code></pre>

<p>It was being set at <code>max_val</code> because the Colorbar class has the call <code>mappable.autoscale_None()</code> in its <code>__init__</code>, which was setting <code>vmax</code> to <code>data.max()</code>, i.e. 69.</p>

<p>I <em>think</em> I am just a victim of using the <code>LinearSegmentedColormap</code> in the wrong way. I want discrete values assigned to specific colors, but the display of a colorbar associated with <code>LinearSegmentedColormap</code> assumes continuous data and therefore defaults to setting unspecified limits to <code>data.min()</code> and <code>data.max()</code>, i.e. in this case 0 and 69.</p>

python matplotlib colorbar