1

I am trying to create a color bar using the color map seismic. I want the color map to be in the range from -6 to 6 but be white from -1.5 to -.5 and then start diverging from there with red for numbers greater than -.5 and blue for less than -1.5.

Is there any easy way to do this?

I was trying this:

lower = plt.cm.seismic(np.linspace(-6, -1.5, 10))
upper = plt.cm.seismic(np.linspace(-.5, 6, 10))
colors = np.vstack((lower, upper))
tmap = matplotlib.colors.LinearSegmentedColormap.from_list('map_white', colors)
ghovat
  • 1,033
  • 1
  • 12
  • 38
Zmann3000
  • 806
  • 5
  • 13

1 Answers1

5

A. Create new colormap

You can indeed create a new colormap specifically for this case,

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap

p = [-6, -1.5, 0.5, 6]
f = lambda x: np.interp(x, p, [0, 0.5, 0.5, 1])

cmap = LinearSegmentedColormap.from_list('map_white', 
              list(zip(np.linspace(0,1), plt.cm.seismic(f(np.linspace(min(p), max(p)))))))

plt.imshow(np.random.rand(10,10)*12-6, vmin=min(p), vmax=max(p), cmap=cmap)
plt.colorbar()

plt.show()

B. Create new normalization

Alternatively, create a new normalization with two inner points, which are interpolated to. This is similar to the answer to merge-colormaps-in-matplotlib, just with the two points being almost equal.

import numpy as np
import matplotlib.pyplot as plt


class StretchOutNormalize(plt.Normalize):
    def __init__(self, vmin=None, vmax=None, low=None, up=None, clip=False):
        self.low = low
        self.up = up
        plt.Normalize.__init__(self, vmin, vmax, clip)

    def __call__(self, value, clip=None):
        x, y = [self.vmin, self.low, self.up, self.vmax], [0, 0.5-1e-9, 0.5+1e-9, 1]
        return np.ma.masked_array(np.interp(value, x, y))


norm=StretchOutNormalize(vmin=-6, vmax=6, low=-1.5, up=0.5)

plt.imshow(np.random.rand(10,10)*12-6, cmap="seismic", norm=norm)
plt.colorbar()

plt.show()

In both cases the result is the same:

pic

ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712