Reputation: 73
I'm trying to plot data in the range 0-69 with a bespoke colormap. Here is an example:
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()
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).
I've tried setting the data and view intervals from [0, 69] to [0, 70]:
cb.locator.axis.set_view_interval(0, 70)
cb.locator.axis.set_data_interval(0, 70)
cb.update_ticks()
but this doesn't appear to do anything.
Please can someone advise?
Upvotes: 1
Views: 838
Reputation: 73
The simplest way to solve my problem was to set vmax
in the definition of the mappable:
ax = plt.imshow(data, cmap=cmap, interpolation='nearest', vmax=max_val + 1)
It was being set at max_val
because the Colorbar class has the call mappable.autoscale_None()
in its __init__
, which was setting vmax
to data.max()
, i.e. 69.
I think I am just a victim of using the LinearSegmentedColormap
in the wrong way. I want discrete values assigned to specific colors, but the display of a colorbar associated with LinearSegmentedColormap
assumes continuous data and therefore defaults to setting unspecified limits to data.min()
and data.max()
, i.e. in this case 0 and 69.
Upvotes: 1