matplotlib标准颜色映射用法

matplotlib标准颜色映射用法,matplotlib,colorbar,color-mapping,Matplotlib,Colorbar,Color Mapping,我正在使用matplotlib 1.3.0,我有以下几点: import matplotlib.pyplot as plt cmap = plt.cm.jet plt.contourf([[.12, .2], [.8, 2]], levels=[0, .1, .3, .5, 1, 3], cmap=cmap, vmin=0, vmax=3) plt.colorbar() 产生: 我不明白的是,其他颜色都到哪里去了?据我所知,通过指定vmin=0,vmax=3,色条应使用整个cmap范围,如下

我正在使用matplotlib 1.3.0,我有以下几点:

import matplotlib.pyplot as plt
cmap = plt.cm.jet
plt.contourf([[.12, .2], [.8, 2]], levels=[0, .1, .3, .5, 1, 3], cmap=cmap, vmin=0, vmax=3)
plt.colorbar()
产生:

我不明白的是,其他颜色都到哪里去了?据我所知,通过指定
vmin=0
vmax=3
,色条应使用整个
cmap
范围,如下图所示:

这是在不提供
vmin
vmax
级别
参数的情况下生成的。所以我错过了什么

编辑1

响应tom10&tcaswell。我本以为会像你说的那样,但是。。。不幸的是,事实并非如此。看看这个:

plt.contourf([[.12, .2], [.8, 3.2]], levels=[0, .1, .3, .5, 1, 3], cmap=cmap, vmin=0, vmax=3)
plt.colorbar()
与:

也许要澄清一点:假设我有数据,它的重要特性大约是0.1,但也有一些大约是3。所以我给它一个
级别=[0,0.005,0.075,0.1,0.125,0.15,0.2,1,2.5,2.75,3,3.25]
vmin=0,vmax=3.25
。现在我希望看到整个颜色范围,但是所有重要的数据点0.005到0.125最终都位于蓝色区域(通过使用标准
plt.cm.jet
color map)。我想我说的是。。。如果我给出
levels=[0,1,2,3],vmin=0,vmax=3
对于一些从0到3的数据,我希望看到给定颜色映射中的所有颜色,但是如果我给出
levels=[0,0.9,0.1,0.11,1,3],vmi=0,vmax=3,我希望看到给定颜色映射中的所有颜色,除了映射到正确的间隔,相反,我看到一束蓝色在0-0.11区域着色,一些绿色/黄色在区域的其他部分着色。希望这能让它。。。有点清楚

编辑2

即使我没有给出任何
norm
vmin,vmax
,也会发生同样的情况

编辑3

参考tcaswell的评论,按照它的方式行事。。。至少对我来说,这是违反直觉的。我希望颜色在某种程度上独立于数据点。我希望colormap中的所有颜色都会一直使用(除非
vmin,vmax
大于/小于
级别
min,max值)。换句话说,看看我不久前编写的代码(Python 3):

然后将其用作:

levels = [0, .1, .3, .5, 1, 3]
cmapData = discretize(plt.cm.jet, bounds=levels)
plt.contourf([[.12, .2], [.8, 3.2]], levels=levels, cmap=cmapData['cmap'], norm=cmapData['norm'])
plt.colorbar()
它给出了一个图,在该图中,您可以实际区分特征(0.1-0.5),即,通过使用上述方法和
plt.cm.jet
,它们不再位于蓝色区域:


我是说,我知道我解决了这个问题,不久前。。。但我想我的问题是。。。为什么matplotlib中的默认值不是这个?我本以为会是这样的。。。或者,它可能只是一个配置/参数/一些默认情况下启用此功能的东西,而我缺少了它?

填充区域的颜色是由它填充的两条线(iirc)的中点拾取的。您看到的黄色是您设置的颜色映射和限制下的
2

如果要按区域索引映射颜色,请执行一些猴子修补:

def _process_colors_by_index(self):
    """
    Color argument processing for contouring.

    The color is based in the index in the level set, not
    the actual value of the level.

    """
    self.monochrome = self.cmap.monochrome
    if self.colors is not None:
        # Generate integers for direct indexing.
        i0, i1 = 0, len(self.levels)
        if self.filled:
            i1 -= 1
        # Out of range indices for over and under:
        if self.extend in ('both', 'min'):
            i0 = -1
        if self.extend in ('both', 'max'):
            i1 += 1
        self.cvalues = list(range(i0, i1))
        self.set_norm(colors.NoNorm())
    else:
        self.cvalues = range(len(self.levels))
    self.set_array(range(len(self.levels)))
    self.autoscale_None()
    if self.extend in ('both', 'max', 'min'):
        self.norm.clip = False

    # self.tcolors are set by the "changed" method


orig = matplotlib.contour.ContourSet._process_colors
matplotlib.contour.ContourSet._process_colors = _process_colors_by_index
cmap = plt.cm.jet
figure()
out = plt.contourf([[.12, .2], [.8, 2]], levels=[0, .1, .3, .5, 1, 3], cmap=cmap)
plt.colorbar()
# fix what we have done
matplotlib.contour.ContourSet._process_colors = orig

您可能会做得更好,并将换档也减少1/2

您还可以进入并仅更改现有轮廓的颜色。看起来您需要更改
out.cvalues
的值,然后对对象调用
out.changed()


破坏性较小的版本是通过对
matplotlib.colors.Normalize进行子分类来编写自定义
norm
,有关模板,请参阅

数据的最大值为
2
。在相关绘图中,您设置了
vmax=3


更详细地说,
vmax
设置贴图中使用的颜色范围。因为这比数据范围大得多,所以在绘制数据时,无法看到完整的颜色范围。您选择的少量
级别进一步混淆了这一点,它没有显示所有可用的颜色,因为颜色栏仅显示整个1到3范围内的单一颜色,再次模糊了2以外的可用颜色。

实际上,我认为最好的解决方案位于以下位置:

它定义了一个解决所有问题的小类:

class nlcmap(mc.LinearSegmentedColormap):
    """A nonlinear colormap"""

    name = 'nlcmap'

    def __init__(self, cmap, levels):
        self.cmap = cmap
        # @MRR: Need to add N for backend
        self.N = cmap.N
        self.monochrome = self.cmap.monochrome
        self.levels = np.asarray(levels, dtype='float64')
        self._x = self.levels / self.levels.max()
        self._y = np.linspace(0.0, 1.0, len(self.levels))

    #@MRR Need to add **kw for 'bytes'
    def __call__(self, xi, alpha=1.0, **kw):
        yi = np.interp(xi, self._x, self._y)
        return self.cmap(yi, alpha)

这个剧本最初是由一个叫罗伯特·赫特兰的人写的。所有的细节都在上面的链接中。

经过一段时间的思考,这个问题的答案似乎比我想象的要简单得多。先解释一下。在阅读
matplotlib.colors
中有关规范化类的文档时,我发现。。。嗯,
matplotlib.colors.BoundaryNorm
应该在这里使用!但正如您在下面的示例中所看到的,有些地方出了问题:

import matplotlib.pyplot as plt
import matplotlib.colors as mc
levels = [0, .1, .3, .5, 1, 3]
norm = mc.BoundaryNorm(levels, len(levels)-1)
plt.contourf([[.12, .2], [.8, 2]], levels=levels, norm=norm)
plt.colorbar()
plt.show()
因此: 这显然是我们不想要的!我在想。。。为什么您必须给
BoundaryNorm
的构造函数提供要使用的颜色数?。。。
BoundaryNorm
不应该使用颜色映射的全部范围吗?然后我突然想到,上面的代码只做了一点修改:

# use here 256 instead of len(levels)-1 becuase
# as it's mentioned in the documentation for the
# colormaps, the default colormaps use 256 colors in their
# definition: print(plt.cm.jet.N) for example
norm = mc.BoundaryNorm(levels, 256)
我们得到: 这正是我们想要的

或者我们可以:

cmap = # user define cmap
norm = mc.BoundaryNorm(levels, cmap.N)
# which is I guess a little bit more programatically (is this a word?!) correct

您的更新行为完全符合我的预期。黄色仍然是2,你的顶线(你没有画)是红色的,3轮廓上方是白色的,因为它超出了你的级别。好吧,我想我知道了如何使用默认颜色贴图(我不介意白色),但是。。。那么,有没有一种方法可以让颜色像我期望的那样表现呢?比如说,为了简单起见,使用从c0到c8的颜色映射,但我还是指默认的颜色映射):当我设置
levels=[0,0.09,0.1,0.11,3]
时,我希望它使用[c0(0-0.09)、c2(0.09-0.1)、c4(0.09-0.1)、c6(0.1-0.11)、c8(0.11-0.3)],而不是使用[c0(0-0.09)、c1(0.09-0.1)、c2(0.01-0.11)、c6(0.11-3)]。希望这是有意义的…好吧,但那不是你做的。彩色地图对你的等级一无所知
cmap = # user define cmap
norm = mc.BoundaryNorm(levels, cmap.N)
# which is I guess a little bit more programatically (is this a word?!) correct