python - Merge colormaps in matplotlib -
i want merge 2 colormaps imshow plot. want use 'rdbu' range -0.4 0.4, 0.4 maximum value (say 1.5) want use gradient same blue color (say green example).
how can that?
this how far got far:
import numpy np import matplotlib.pyplot plt import matplotlib.colors colors matplotlib.mlab import bivariate_normal n = 100 ''' custom norm: example customized normalization. 1 uses example above, , normalizes negative data differently positive. ''' x, y = np.mgrid[-3:3:complex(0, n), -2:2:complex(0, n)] z1 = (bivariate_normal(x, y, 1., 1., 1.0, 1.0))**2 \ - 0.4 * (bivariate_normal(x, y, 1.0, 1.0, -1.0, 0.0))**2 z1 = z1/0.03 # example of making own norm. see matplotlib.colors. # joe kington: 1 gives 2 different linear ramps: class midpointnormalize(colors.normalize): def __init__(self, vmin=none, vmax=none, midpoint=none, clip=false): self.midpoint = midpoint colors.normalize.__init__(self, vmin, vmax, clip) def __call__(self, value, clip=none): # i'm ignoring masked values , kinds of edge cases make # simple example... x, y = [self.vmin, self.midpoint, self.vmax], [0, 0.5, 1] return np.ma.masked_array(np.interp(value, x, y)) fig, ax = plt.subplots(1, 1) minvalue = z1.min() maxvalue = 0.4 pcm = ax.imshow(z1, norm=midpointnormalize(midpoint=0.), vmin=minvalue, vmax=maxvalue, cmap='rdbu', origin='lower', aspect=1.0, interpolation='none') cbar = fig.colorbar(pcm, ax=ax, extend='both', ticks=[minvalue, 0.0, maxvalue]) fig.tight_layout() plt.show()
the purpose create colormapping, has several predefined values. start of colormap should @ vmin
, white (which in middle of "rdbu" colormap) should @ 0
, predefined point (0.4
) shall upper end of rdbu
colormap , color shall fade towards end color.
for purpose need 2 things. (a) colormap has colors in , (b) normalization allows map intermediate points respective colors.
(a) creating colormap
colormaps range between 0 , 1. may create colormap such colors "rdbu" colormap extend on first half of desired colormap, such 0 red, 0.25 white , 0.5 blue. second half of colormap ranges 0.5 (the same blue) on intermediate turquoise @ 0.75 green @ 1. (the intermediate turquoise chosen because direct transition blue green result in smeared brownish blue in middle, undesired.) steps accomplished via following code
colors = plt.cm.rdbu(np.linspace(0,1.,128)) colors = zip(np.linspace(0,0.5,128),colors) colors += [ (0.75,"#1fa187"),(1., "#76d154")] cmap = matplotlib.colors.linearsegmentedcolormap.from_list('mycmap', colors)
such cmap
desired colormap.
(b) creating normalization
unlike midpointnormalization, has 1 intermediate point, need 2 intermediate points: 1 being white color @ 0 value , 1 being end of first half of colormap. can hence use 2 values in custom normalization (here called low
, up
), such interpolation ranges on 4 points in total , low
corresponds 0.25 value of colormap , up
corresponds 0.5 value.
x, y = [self.vmin, self.low, self.up, self.vmax], [0, 0.25, 0.5, 1]
complete code:
import numpy np import matplotlib.pyplot plt import matplotlib.colors matplotlib.mlab import bivariate_normal n = 100 x, y = np.mgrid[-3:3:complex(0, n), -2:2:complex(0, n)] z1 = (bivariate_normal(x, y, 1., 1., 1.0, 1.0))**2 \ - 0.4 * (bivariate_normal(x, y, 1.0, 1.0, -1.0, 0.0))**2 z1 = z1/0.03 class twoinnerpointsnormalize(matplotlib.colors.normalize): def __init__(self, vmin=none, vmax=none, low=none, up=none, clip=false): self.low = low self.up = matplotlib.colors.normalize.__init__(self, vmin, vmax, clip) def __call__(self, value, clip=none): x, y = [self.vmin, self.low, self.up, self.vmax], [0, 0.25, 0.5, 1] return np.ma.masked_array(np.interp(value, x, y)) colors = plt.cm.rdbu(np.linspace(0,1.,128)) colors = zip(np.linspace(0,0.5,128),colors) colors += [ (0.75,"#1fa187"),(1., "#76d154")] cmap = matplotlib.colors.linearsegmentedcolormap.from_list('mycmap', colors) fig, ax = plt.subplots(1, 1) norm = twoinnerpointsnormalize(vmin=-0.4, vmax=1.5, low=0., up=0.4) pcm = ax.imshow(z1, norm=norm, cmap=cmap, origin='lower', aspect=1.0, interpolation='none') cbar = fig.colorbar(pcm, ax=ax, ticks=[-0.4,0.0, 0.4,1.5]) fig.tight_layout() plt.show()
Comments
Post a Comment