I am trying to create a custom colormap using pyplot
for a figure produced using pcolormesh
. I would like the colormap to be non-uniform. I want to be able to pick out small changes while grouping larger changes together. Sort of like the idea of a logarithmic colormap, without necessarily being logarithmic.
However, the colors that I expect to show up on the colorbar are not all there. Here is some code to reproduce this:
from matplotlib import pyplot as plt
from matplotlib.colors import LinearSegmentedColormap
import numpy as np
cbins = [-10., -5., -2., -1., -0.5, -0.1, 0.1, 0.5, 1., 2., 5., 10.] # log-ish colormap bins
# cbins = np.arange(-10, 11, 2) # linear colormap bins
colors = [(0.0, 0.0, 0.0), # a terrible grayscale colormap, for illustration
(0.2, 0.2, 0.2),
(0.4, 0.4, 0.4),
(0.6, 0.6, 0.6),
(0.8, 0.8, 0.8),
(1.0, 1.0, 1.0),
(0.8, 0.8, 0.8),
(0.6, 0.6, 0.6),
(0.4, 0.4, 0.4),
(0.2, 0.2, 0.2),
(0.0, 0.0, 0.0),
]
cmap = LinearSegmentedColormap.from_list('test', colors, N=len(cbins)-1) # converted to colormap
x = (np.random.rand(20, 20) * 20) - 10 # array of random values between -10 and +10
p = plt.pcolormesh(x, cmap=cmap, vmin=min(cbins), vmax=max(cbins)) # plotted
plt.colorbar(p, boundaries=cbins, spacing='uniform', ticks=cbins) # ticks and boundaries set
Below is the plot I get as a result.
colorbar with repeated colors at the center and missing colors at the extremes
I would expect white to appear in the central bin (-0.1, 0.1), followed by light gray and so on, with black at the outer bins.
When I uncomment the line with linear colormap bins, it works as expected. See the image below.
colorbar with all expected colors present
Am I missing something obvious? I've searched for a couple hours now without any luck.
I am using python 3.8.12 with matplotlib 3.4.3. Incidentally, the result is somewhat different (worse) with matplotlib 3.5.0... as if the spacing='uniform'
does not work.