Linking colors from a continuous color scheme to specific values ​​in matplotlib

I am trying to find a way to associate specific data values ​​with specific colors in a continuous color palette.

I have a specific image with values ​​from [min, max]

, and I would like the following values [min, q1, q2, q3, max]

, where q'n'

refers to the quartiles that should be associated with the colors that match [0, 0.25. 0.5, 0.75. 1.0]

in the color selection. As a result, the midpoint of the color will correspond to the median value in the image, etc ...

I have been looking around but I have not been able to find a way to do this.

+3


source to share


1 answer


You will need to subclass matplotlib.colors.Normalize

and pass an instance of your new norm

to imshow

/ contourf

/ whatever plotting function you use.

The basic idea is illustrated in the first variation here: Shifting the colorbar matplotlib (Don't reverse one of my own questions too much, but I can't think of another example.)

However, this question is specifically about setting one data value corresponding to 0.5 in the color palette. 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()

      

enter image description here

Note that 0.5 in the color palette (white) corresponds to a data value of 0, and the red and blue regions of the color scheme are asymmetric (note the wide "pink" range compared to the much narrower transition to dark blue).

+3


source







All Articles