  C RUBY-ON-RAILS MYSQL ASP.NET DEVELOPMENT RUBY .NET LINUX SQL-SERVER REGEX WINDOWS ALGORITHM ECLIPSE VISUAL-STUDIO STRING SVN PERFORMANCE APACHE-FLEX UNIT-TESTING SECURITY LINQ UNIX MATH EMAIL OOP LANGUAGE-AGNOSTIC VB6 MSBUILD # Nonlinear colormap with Matplotlib  » python » Nonlinear colormap with Matplotlib

By : Pinky
Date : November 21 2020, 09:01 AM
this one helps. In the example where levels1 = [-50, -20, -9, -6, -3, -2, -1, 0] you are dividing by zero when you say self._x = self.levels/ self.levels.max() . It seems that functions like pcolor and contourf rescale the input data between 0 and 1 before passing them to the colormap. Hence you also need to rescale your levels to that range, which your code does for the first example but not for the second. This seems to work: code :
``````class nlcmap(LinearSegmentedColormap):
"""A nonlinear colormap"""

name = 'nlcmap'

def __init__(self, cmap, levels):
self.cmap = cmap
self.monochrome = self.cmap.monochrome
self.levels = asarray(levels, dtype='float64')
self._x = self.levels-self.levels.min()
self._x/= self._x.max()
self._y = linspace(0, 1, len(self.levels))

def __call__(self, xi, alpha=1.0, **kw):
yi = interp(xi, self._x, self._y)
return self.cmap(yi, alpha)
`````` ## how to extract a subset of a colormap as a new colormap in matplotlib?

Date : March 29 2020, 07:55 AM
To fix this issue The staticmethod colors.LinearSegmentedColormap.from_list can be used to create new LinearSegmentedColormaps. Below, I sample the original colormap at 100 points between 0.2 and 0.8:
code :
``````cmap(np.linspace(0.2, 0.8, 100))
``````
``````import matplotlib.pyplot as plt
import matplotlib.colors as colors
import numpy as np

def truncate_colormap(cmap, minval=0.0, maxval=1.0, n=100):
new_cmap = colors.LinearSegmentedColormap.from_list(
'trunc({n},{a:.2f},{b:.2f})'.format(n=cmap.name, a=minval, b=maxval),
cmap(np.linspace(minval, maxval, n)))
return new_cmap

arr = np.linspace(0, 50, 100).reshape((10, 10))
fig, ax = plt.subplots(ncols=2)

cmap = plt.get_cmap('jet')
new_cmap = truncate_colormap(cmap, 0.2, 0.8)
ax.imshow(arr, interpolation='nearest', cmap=cmap)
ax.imshow(arr, interpolation='nearest', cmap=new_cmap)
plt.show()
`````` ## nonlinear colormap, matplotlib

By : Eqls
Date : March 29 2020, 07:55 AM
this one helps. Your link provides quite a good solution for the colormap. I edited a bit, but it contained al the necessary. You need to pick some sensible levels for your nonlinear colormap. I used two ranges centered around the mean values, between +- 4 the standard deviation of your sample. by changing that to another number you obtain a different local gradient in the color around the two mean values.
For the colorbar, you
code :
``````import numpy as np
import matplotlib.pyplot as plt

x = y = np.linspace(1, 10, 10)

t1mean, t2mean = 2, 9
sigma1, sigma2 = .3, .01
t1 = np.random.normal(t1mean, sigma1, 10)
t2 = np.random.normal(t2mean, sigma2, 10)

class nlcmap(object):
def __init__(self, cmap, levels):
self.cmap = cmap
self.N = cmap.N
self.monochrome = self.cmap.monochrome
self.levels = np.asarray(levels, dtype='float64')
self._x = self.levels
self.levmax = self.levels.max()
self.transformed_levels = np.linspace(0.0, self.levmax,
len(self.levels))

def __call__(self, xi, alpha=1.0, **kw):
yi = np.interp(xi, self._x, self.transformed_levels)
return self.cmap(yi / self.levmax, alpha)

tmax = max(t1.max(), t2.max())
#the choice of the levels depends on the data:
levels = np.concatenate((
[0, tmax],
np.linspace(t1mean - 4 * sigma1, t1mean + 4 * sigma1, 5),
np.linspace(t2mean - 4 * sigma2, t2mean + 4 * sigma2, 5),
))

levels = levels[levels <= tmax]
levels.sort()

cmap_nonlin = nlcmap(plt.cm.jet, levels)

fig, (ax1, ax2) = plt.subplots(1, 2)

ax1.scatter(x, y, edgecolors=cmap_nonlin(t1), s=15, linewidths=4)
ax2.scatter(x, y, edgecolors=cmap_nonlin(t2), s=15, linewidths=4)

cbar_ax = fig.add_axes([0.10, 0.15, 0.05, 0.7])

#for the colorbar we map the original colormap, not the nonlinear one:
sm = plt.cm.ScalarMappable(cmap=plt.cm.jet,
norm=plt.Normalize(vmin=0, vmax=tmax))
sm._A = []

cbar = fig.colorbar(sm, cax=cbar_ax)
#here we are relabel the linear colorbar ticks to match the nonlinear ticks
cbar.set_ticks(cmap_nonlin.transformed_levels)
cbar.set_ticklabels(["%.2f" % lev for lev in levels])

plt.show()
`````` ## Nonlinear Colormap/Heatmap

By : IngoB
Date : March 29 2020, 07:55 AM
This might help you I cannot tell why the colormap does not use the full range of colors in your example, but it seems that the following is closer to the result you want (i.e. it does span a larger range of colors with the quantile levels).
code :
``````...
hm = plt.contourf(x, levels = levels, cmap = "rainbow", vmax = levels[-2])
...
``````
``````...
hm = plt.contourf(x, levels = levels, cmap = "rainbow", vmax = 0.3 * levels[-1] + 0.7 * levels[-2])
...
`````` ## weird colormap when map the scalar value to RGB using matplotlib.colors.Colormap

By : DimaK
Date : March 29 2020, 07:55 AM
fixed the issue. Will look into that further In your format function, you're left aligning, not right aligning, causing the weird value jumps. See this line:
code :
``````curr_cstr = '#{:0<2}{:0<2}{:0<2}'.format(hex(r)[2:], hex(g)[2:], hex(b)[2:])
``````
``````import matplotlib.pyplot as plt
import numpy as np
plt.ioff()

cmap = 'RdBu_r'
cmap = plt.get_cmap(cmap)

f = plt.figure(figsize=(8, 4))
plot_arr = np.arange(100).reshape((10, 10)) / 99.
ax1.imshow(plot_arr, vmin=0., vmax=1., cmap=cmap, interpolation='nearest')

for i in range(10):
for j in range(10):
curr_rgb = cmap(plot_arr[i, j])[0:3]
curr_rgb = tuple([int(x * 255) for x in curr_rgb])
r, g, b = curr_rgb
curr_cstr = '#{:0>2}{:0>2}{:0>2}'.format(hex(r)[2:], hex(g)[2:], hex(b)[2:])
ax2.plot(j, i, 'o', mfc=curr_cstr, lw=0, mec='none', ms=20)

ax2.set_xlim([-0.5, 9.5])
ax2.set_ylim([9.5, -0.5])
plt.show()
``````
``````if i==9: print i ,j, curr_rgb, curr_cstr

9 0 (170, 21, 41) #001500
9 1 (161, 18, 40) #001200
9 2 (155, 16, 39) #001000
9 3 (147, 14, 38) #00e000
9 4 (138, 11, 36) #00b000
9 5 (132, 9, 35) #009000
9 6 (123, 6, 34) #006000
9 7 (117, 4, 33) #004000
9 8 (108, 1, 31) #001000
9 9 (103, 0, 31) #000000
`````` ## Matlab colormap & caxis matching nonlinear plots

By : Vebjørn Scream Storb
Date : March 29 2020, 07:55 AM
I wish this help you The problem here is that the colormap you're trying to mimic is non-linear, but MATLAB maps the data to a colormap in a linear fashion. You can solve this by first binning your data using histcounts to create a linear mapping, then adjusting the color bar ticks labels to make your linear colormap appear non-linear. Here's an example:
code :
``````data = 2.5.*rand(200);         % Sample random data in the range [0 2.5]
edges = [0 0.5 0.75 0.9 1.1 1.25 1.5 2 2.5];  % Define edges of nonlinear map
imgMap = [0.00 0.00 0.50; ...  % Colormap colors
0.00 0.50 1.00; ...
0.67 0.90 0.93; ...
1.00 1.00 1.00; ...
1.00 0.87 0.68; ...
0.98 0.67 0.38; ...
1.00 0.40 0.10; ...
1.00 0.00 0.00];

[~, ~, bin] = histcounts(data, edges);  % Bin the data according to the edges

image(bin);                  % Plot bin index, not the original data
``````bin(bin == 0) = nan; 