如何在matplotlib中提取色图的子集作为新的色图?

ran*_*ana 39 python matplotlib

我想使用matplotlib的色图,例如CMRmap.但我不想在开头使用"黑色"颜色,最后使用"白色"颜色.我有兴趣使用中间颜色绘制我的数据.我认为人们经常使用它,但我在互联网上搜索,无法找到任何简单的解决方案.如果有人建议任何解决方案,我将不胜感激.

unu*_*tbu 56

staticmethod colors.LinearSegmentedColormap.from_list可用于创建新的LinearSegmentedColormaps.下面,我在0.2和0.8之间的100点处对原始色彩图进行采样:

cmap(np.linspace(0.2, 0.8, 100))
Run Code Online (Sandbox Code Playgroud)

并使用这些颜色生成新的色彩映射:

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[0].imshow(arr, interpolation='nearest', cmap=cmap)
ax[1].imshow(arr, interpolation='nearest', cmap=new_cmap)
plt.show()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

左侧的图表使用原始色彩图(在此示例中jet)显示图像.右侧的图显示使用相同的图像new_cmap.


131*_*13e 15

在我的 CMasher 包中,我提供了 -get_sub_cmap()函数(https://cmasher.readthedocs.io/user/usage.html#sub-colormaps),它接受颜色图和范围,并返回包含请求范围的新颜色图。

因此,举例来说,如果您想要获取颜色图 20% 到 80% 之间的颜色viridis,您可以使用以下命令来实现:

import cmasher as cmr

cmap = cmr.get_sub_cmap('viridis', 0.2, 0.8)
Run Code Online (Sandbox Code Playgroud)

PS:不要使用jet(或CMRmap),因为它们在感知上不是统一的顺序。相反,请使用 matplotlib 中的 5 个正确的颜色图或 cmocean 或我的 CMasher 提供的颜色图。

编辑:在最新版本的 CMasher 中,人们还可以使用同一函数通过向函数提供要采用的段数来从任何颜色图创建离散/定性颜色图。例如,如果您想创建viridis20% 到 80% 范围内的定性色彩图,您可以使用以下命令执行此操作:

cmap = cmr.get_sub_map('viridis', 0.2, 0.8, N=5)
Run Code Online (Sandbox Code Playgroud)


wfl*_*nny 8

我最近才在自己身上挣扎.这是一些可能的解决方案:


尝试使用vmin,vmax在你的绘图功能关键字参数.例如,假设您的数据介于0和1之间,但不喜欢颜色图的极值为0和1使用的颜色.

import matplotlib.pyplot as plt
import matplotlib.cm as cm

my_cmap = cm.spectral_r
my_cmap.set_over('c')
my_cmap.set_under('m')
plt.pcolor(data, vmin=0.01, vmax=0.99, cmap=my_cmap)
Run Code Online (Sandbox Code Playgroud)

这将强制整个色彩图用于0.01和0.99之间的值,而高于和低于的值将分别为青色和品红色.这可能无法准确解决您的问题,但如果您喜欢特定的色彩图并希望它在两端都有其他颜色,那么它可能会很有用.


如果您真的想要更改色彩映射,请查看此处的文档以及此处LinearSegmentedColormap.

第一,

import matplotlib.cm as cm
cdict = cm.get_cmap('spectral_r')._segmentdata
Run Code Online (Sandbox Code Playgroud)

这将返回构成色彩映射的所有颜色的字典.然而,弄清楚如何改变这本字典是非常棘手的.这个词有三个键,red, green, blue.cdict[key]返回表单的值列表(x, y0, y1).我们来看看两个连续的元素cdict['red']:

((0.0, 0.0, 0.0)
 (0.5, 1.0, 1.0),...
Run Code Online (Sandbox Code Playgroud)

这意味着具有z(假设我们正在执行a pcolorimshow)介于0.0和0.5之间的数据将使与该数据相关联的rgb颜色的红色分量将从0.0(无红色)增加到1.0(最大红色).这意味着要更改色彩映射的颜色,您必须检查rgb的三个组件中的每个组件如何在您感兴趣的色彩映射区域中进行插值.只需确保每种颜色,第一个和最后一个颜色.入口分别以x=0x=1; 你必须涵盖[0,1]的整个范围.

如果要更改开始和结束颜色,请尝试

import matplotlib.cm as cm
from matplotlib.colors import LinearSegmentedColormap
cdict = cm.get_cmap('spectral_r')._segmentdata

cdict['red'][0] = (0, 0.5, 0.5) # x=0 for bottom color in colormap
cdict['blue'][0] = (0, 0.5, 0.5) # y=0.5 gray
cdict['green'][0] = (0, 0.5, 0.5) # y1=y for simple interpolation
cdict['red'][-1] = (1, 0.5, 0.5) # x=1 for top color in colormap
cdict['blue'][-1] = (1, 0.5, 0.5)
cdict['green'][-1] = (1, 0.5, 0.5)

my_cmap = LinearSegmentedColormap('name', cdict)
Run Code Online (Sandbox Code Playgroud)

然后在绘图功能中使用此cmap.


我想要做的是将spectral_rcolormap 末尾的灰色更改为纯白色.这是使用

# Using imports from above
cdict = matplotlib.cm.get_cmap('spectral_r')._segmentdata
cdict['red'][0] = (0, 1, 1)
cdict['green'][0] = (0, 1, 1)
cdict['blue'][0] = (0, 1, 1)
my_cmap = LinearSegmentedColormap('my_cmap', cdict)
Run Code Online (Sandbox Code Playgroud)