I am trying to find a way to associate certain data values to specific colors in a continuous colormap.
I have a certain image with values ranging from [min, max]
, and I would like the following values [min, q1, q2, q3, max]
, where q'n'
refers to the quartiles, to be associated to the colors that correspond to [0, 0.25. 0.5, 0.75. 1.0]
in the colormap of choice. As a result the midpoint of the coloramp would correspond to the median value in the image, and so on...
I have been looking around, but I have not been able to find a way to do this.
You'll need to subclass matplotlib.colors.Normalize
and pass in an instance of your new norm
to imshow
/contourf
/whatever plotting function you're using.
The basic idea is illustrated in the first option here: Shifted colorbar matplotlib (Not to shill one of my own questions too much, but I can't think of another example.)
However, that question deals specifically with setting a single data value to correspond to 0.5 in the colormap. It's not too hard to expand the idea to "piecewise" normalization, though:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import Normalize
class PiecewiseNormalize(Normalize):
def __init__(self, xvalues, cvalues):
self.xvalues = xvalues
self.cvalues = cvalues
Normalize.__init__(self)
def __call__(self, value, clip=None):
# I'm ignoring masked values and all kinds of edge cases to make a
# simple example...
if self.xvalues is not None:
x, y = self.xvalues, self.cvalues
return np.ma.masked_array(np.interp(value, x, y))
else:
return Normalize.__call__(self, value, clip)
data = np.random.random((10,10))
data = 10 * (data - 0.8)
fig, ax = plt.subplots()
norm = PiecewiseNormalize([-8, -1, 0, 1.5, 2], [0, 0.1, 0.5, 0.7, 1])
im = ax.imshow(data, norm=norm, cmap=plt.cm.seismic, interpolation='none')
fig.colorbar(im)
plt.show()
Note that 0.5 in the colormap (white) corresponds to a data value of 0, and the red and blue regions of the colormap are asymmetric (note the broad "pink" range vs the much narrower transition to dark blue).
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