在matplotlib中反转颜色映射
我想知道如何简单地颠倒给定的颜色映射的颜色顺序,以便与plot_surface一起使用它。
标准色彩地图也都有相反的版本。 他们和_r
有相同的名字。 ( 文档在这里。 )
在matplotlib中,一个颜色贴图不是一个列表,但它包含了颜色列表colormap.colors
。 模块matplotlib.colors
提供了一个函数ListedColormap()
来从列表中生成一个颜色映射。 所以你可以通过做反转任何颜色地图
colormap_r = ListedColormap(colormap.colors[::-1])
由于LinearSegmentedColormaps
基于红色,绿色和蓝色字典,因此需要对每个项目进行反转:
import matplotlib.pyplot as plt import matplotlib as mpl def reverse_colourmap(cmap, name = 'my_cmap_r'): """ In: cmap, name Out: my_cmap_r Explanation: t[0] goes from 0 to 1 row i: x y0 y1 -> t[0] t[1] t[2] / / row i+1: x y0 y1 -> t[n] t[1] t[2] so the inverse should do the same: row i+1: x y1 y0 -> 1-t[0] t[2] t[1] / / row i: x y1 y0 -> 1-t[n] t[2] t[1] """ reverse = [] k = [] for key in cmap._segmentdata: k.append(key) channel = cmap._segmentdata[key] data = [] for t in channel: data.append((1-t[0],t[2],t[1])) reverse.append(sorted(data)) LinearL = dict(zip(k,reverse)) my_cmap_r = mpl.colors.LinearSegmentedColormap(name, LinearL) return my_cmap_r
看到它的作品:
my_cmap <matplotlib.colors.LinearSegmentedColormap at 0xd5a0518> my_cmap_r = reverse_colourmap(my_cmap) fig = plt.figure(figsize=(8, 2)) ax1 = fig.add_axes([0.05, 0.80, 0.9, 0.15]) ax2 = fig.add_axes([0.05, 0.475, 0.9, 0.15]) norm = mpl.colors.Normalize(vmin=0, vmax=1) cb1 = mpl.colorbar.ColorbarBase(ax1, cmap = my_cmap, norm=norm,orientation='horizontal') cb2 = mpl.colorbar.ColorbarBase(ax2, cmap = my_cmap_r, norm=norm, orientation='horizontal')
编辑
我没有得到user3445587的评论。 它在彩虹色图上工作正常:
cmap = mpl.cm.jet cmap_r = reverse_colourmap(cmap) fig = plt.figure(figsize=(8, 2)) ax1 = fig.add_axes([0.05, 0.80, 0.9, 0.15]) ax2 = fig.add_axes([0.05, 0.475, 0.9, 0.15]) norm = mpl.colors.Normalize(vmin=0, vmax=1) cb1 = mpl.colorbar.ColorbarBase(ax1, cmap = cmap, norm=norm,orientation='horizontal') cb2 = mpl.colorbar.ColorbarBase(ax2, cmap = cmap_r, norm=norm, orientation='horizontal')
但是它对于自定义声明的色彩地图特别适用,因为自定义声明的色彩地图没有默认的_r
。 以下示例来自http://matplotlib.org/examples/pylab_examples/custom_cmap.html :
cdict1 = {'red': ((0.0, 0.0, 0.0), (0.5, 0.0, 0.1), (1.0, 1.0, 1.0)), 'green': ((0.0, 0.0, 0.0), (1.0, 0.0, 0.0)), 'blue': ((0.0, 0.0, 1.0), (0.5, 0.1, 0.0), (1.0, 0.0, 0.0)) } blue_red1 = mpl.colors.LinearSegmentedColormap('BlueRed1', cdict1) blue_red1_r = reverse_colourmap(blue_red1) fig = plt.figure(figsize=(8, 2)) ax1 = fig.add_axes([0.05, 0.80, 0.9, 0.15]) ax2 = fig.add_axes([0.05, 0.475, 0.9, 0.15]) norm = mpl.colors.Normalize(vmin=0, vmax=1) cb1 = mpl.colorbar.ColorbarBase(ax1, cmap = blue_red1, norm=norm,orientation='horizontal') cb2 = mpl.colorbar.ColorbarBase(ax2, cmap = blue_red1_r, norm=norm, orientation='horizontal')
有两种types的LinearSegmentedColormaps。 在某些情况下,_segmentdata是明确给出的,例如,对于jet:
>>> cm.jet._segmentdata {'blue': ((0.0, 0.5, 0.5), (0.11, 1, 1), (0.34, 1, 1), (0.65, 0, 0), (1, 0, 0)), 'red': ((0.0, 0, 0), (0.35, 0, 0), (0.66, 1, 1), (0.89, 1, 1), (1, 0.5, 0.5)), 'green': ((0.0, 0, 0), (0.125, 0, 0), (0.375, 1, 1), (0.64, 1, 1), (0.91, 0, 0), (1, 0, 0))}
对于彩虹,_segmentdata给出如下:
>>> cm.rainbow._segmentdata {'blue': <function <lambda> at 0x7fac32ac2b70>, 'red': <function <lambda> at 0x7fac32ac7840>, 'green': <function <lambda> at 0x7fac32ac2d08>}
我们可以在matplotlib的源代码中find它们的function
_rainbow_data = { 'red': gfunc[33], # 33: lambda x: np.abs(2 * x - 0.5), 'green': gfunc[13], # 13: lambda x: np.sin(x * np.pi), 'blue': gfunc[10], # 10: lambda x: np.cos(x * np.pi / 2) }
你想要的一切都已经在matplotlib中完成了,只需调用cm.revcmap,这样就可以反转这两种types的segmentdata
cm.revcmap(cm.rainbow._segmentdata)
应该做的工作 – 你可以简单地创build一个新的LinearSegmentData。 在revcmap中,基于SegmentData的函数的反转是通过
def _reverser(f): def freversed(x): return f(1 - x) return freversed
而其他清单则照常倒转
valnew = [(1.0 - x, y1, y0) for x, y0, y1 in reversed(val)]
所以,实际上你想要的是,
def reverse_colourmap(cmap, name = 'my_cmap_r'): return mpl.colors.LinearSegmentedColormap(name, cm.revcmap(cmap._segmentdata))
解决scheme非常简单。 假设你想使用“秋天”色彩图scheme。 标准的逆转:
cmap = matplotlib.cm.autumn
要反转色彩图色谱,请使用get_cmap()函数并将“_r”附加到色彩映射标题,如下所示:
cmap_reversed = matplotlib.cm.get_cmap('autumn_r')
没有反转任意色彩映射的内置方法,但是一个简单的方法是实际上不修改色条,而是创build一个反转的Normalize对象:
from matplotlib.colors import Normalize class InvertedNormalize(Normalize): def __call__(self, *args, **kwargs): return 1 - super(InvertedNormalize, self).__call__(*args, **kwargs)
然后你可以使用plot_surface
和其他Matplotlib绘图function,例如做这个
inverted_norm = InvertedNormalize(vmin=10, vmax=100) ax.plot_surface(..., cmap=<your colormap>, norm=inverted_norm)
这将适用于任何Matplotlib颜色映射。