Matplotlib is hiring a Research Software Engineering Fellow! See discourse for details. Apply by January 3, 2020

Version 3.1.1
matplotlib
Fork me on GitHub

目录

Related Topics

颜色映射规范化

默认情况下使用颜色映射的对象根据数据值线性映射颜色映射中的颜色 vminvmax . 例如::

pcm = ax.pcolormesh(x, y, Z, vmin=-1., vmax=1., cmap='RdBu_r')

将数据映射到 Z 线性从-1到+1,所以 Z=0 将在颜色图的中心给出颜色 RdBu_r (本例中为白色)。

Matplotlib分两步执行此映射,使用来自 [0,1] 先发生,然后映射到颜色映射中的索引。规范化是在 matplotlib.colors() 模块。默认的线性规范化是 matplotlib.colors.Normalize() .

将数据映射到颜色的艺术家传递参数 vminvmax 构建一个 matplotlib.colors.Normalize() 实例,然后调用它:

In [1]: import matplotlib as mpl

In [2]: norm = mpl.colors.Normalize(vmin=-1.,vmax=1.)

In [3]: norm(0.)
Out[3]: 0.5

然而,有时情况下,以非线性方式将数据映射到颜色映射是有用的。

对数的

最常见的转换之一是通过取数据的对数(以10为底)绘制数据。此转换对于显示不同规模的更改非常有用。使用 colors.LogNorm() 通过规范化数据 \(log_{{10}}\) . 在下面的示例中,有两个凸起,一个比另一个小得多。使用 colors.LogNorm() ,可以清楚地看到每个凸起的形状和位置:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as colors

N = 100
X, Y = np.mgrid[-3:3:complex(0, N), -2:2:complex(0, N)]

# A low hump with a spike coming out of the top right.  Needs to have
# z/colour axis on a log scale so we see both hump and spike.  linear
# scale only shows the spike.
Z1 = np.exp(-(X)**2 - (Y)**2)
Z2 = np.exp(-(X * 10)**2 - (Y * 10)**2)
Z = Z1 + 50 * Z2

fig, ax = plt.subplots(2, 1)

pcm = ax[0].pcolor(X, Y, Z,
                   norm=colors.LogNorm(vmin=Z.min(), vmax=Z.max()),
                   cmap='PuBu_r')
fig.colorbar(pcm, ax=ax[0], extend='max')

pcm = ax[1].pcolor(X, Y, Z, cmap='PuBu_r')
fig.colorbar(pcm, ax=ax[1], extend='max')
fig.show()
颜色映射规范化

对称对数

类似地,有时也会有正的和负的数据,但我们仍然希望对两者都应用对数比例。在这种情况下,负数也按对数缩放,并映射到较小的数字;例如,如果 vmin=-vmax ,然后将负数从0映射到0.5,将正数从0.5映射到1。

由于接近零的数值的对数趋于无穷大,因此需要线性映射一个接近零的小范围。参数 直线加速器 允许用户指定此范围的大小(- 直线加速器直线加速器 )颜色映射中此范围的大小由 林鳞 .什么时候? 林鳞 ==1.0(默认值),用于线性范围正负两部分的空间在对数范围内等于10年。

N = 100
X, Y = np.mgrid[-3:3:complex(0, N), -2:2:complex(0, N)]
Z1 = np.exp(-X**2 - Y**2)
Z2 = np.exp(-(X - 1)**2 - (Y - 1)**2)
Z = (Z1 - Z2) * 2

fig, ax = plt.subplots(2, 1)

pcm = ax[0].pcolormesh(X, Y, Z,
                       norm=colors.SymLogNorm(linthresh=0.03, linscale=0.03,
                                              vmin=-1.0, vmax=1.0),
                       cmap='RdBu_r')
fig.colorbar(pcm, ax=ax[0], extend='both')

pcm = ax[1].pcolormesh(X, Y, Z, cmap='RdBu_r', vmin=-np.max(Z))
fig.colorbar(pcm, ax=ax[1], extend='both')
fig.show()
颜色映射规范化

幂律

有时将颜色重新映射到幂律关系(即 \(y=x^{{\gamma}}\) 在哪里 \(\gamma\) 就是力量)。为此,我们使用 colors.PowerNorm() . 作为一个论点 伽马伽马 ==1.0只会产生默认的线性规范化):

注解

使用这种类型的转换绘制数据可能有一个很好的理由。技术查看器用于线性轴和对数轴以及数据转换。权力法不那么常见,观众应该清楚地知道他们已经被使用了。

N = 100
X, Y = np.mgrid[0:3:complex(0, N), 0:2:complex(0, N)]
Z1 = (1 + np.sin(Y * 10.)) * X**(2.)

fig, ax = plt.subplots(2, 1)

pcm = ax[0].pcolormesh(X, Y, Z1, norm=colors.PowerNorm(gamma=0.5),
                       cmap='PuBu_r')
fig.colorbar(pcm, ax=ax[0], extend='max')

pcm = ax[1].pcolormesh(X, Y, Z1, cmap='PuBu_r')
fig.colorbar(pcm, ax=ax[1], extend='max')
fig.show()
颜色映射规范化

离散界限

Matplolib带来的另一个正常化是 colors.BoundaryNorm() . 除了 vminvmax ,这将作为要映射数据之间的参数边界。然后颜色在这些“边界”之间线性分布。例如:

In [4]: import matplotlib.colors as colors

In [5]: bounds = np.array([-0.25, -0.125, 0, 0.5, 1])

In [6]: norm = colors.BoundaryNorm(boundaries=bounds, ncolors=4)

In [7]: print(norm([-0.2,-0.15,-0.02, 0.3, 0.8, 0.99]))
[0 0 1 2 3 3]

注意,与其他规范不同,此规范将值从0返回到 n色品 - 1。

N = 100
X, Y = np.mgrid[-3:3:complex(0, N), -2:2:complex(0, N)]
Z1 = np.exp(-X**2 - Y**2)
Z2 = np.exp(-(X - 1)**2 - (Y - 1)**2)
Z = (Z1 - Z2) * 2

fig, ax = plt.subplots(3, 1, figsize=(8, 8))
ax = ax.flatten()
# even bounds gives a contour-like effect
bounds = np.linspace(-1, 1, 10)
norm = colors.BoundaryNorm(boundaries=bounds, ncolors=256)
pcm = ax[0].pcolormesh(X, Y, Z,
                       norm=norm,
                       cmap='RdBu_r')
fig.colorbar(pcm, ax=ax[0], extend='both', orientation='vertical')

# uneven bounds changes the colormapping:
bounds = np.array([-0.25, -0.125, 0, 0.5, 1])
norm = colors.BoundaryNorm(boundaries=bounds, ncolors=256)
pcm = ax[1].pcolormesh(X, Y, Z, norm=norm, cmap='RdBu_r')
fig.colorbar(pcm, ax=ax[1], extend='both', orientation='vertical')

pcm = ax[2].pcolormesh(X, Y, Z, cmap='RdBu_r', vmin=-np.max(Z))
fig.colorbar(pcm, ax=ax[2], extend='both', orientation='vertical')
fig.show()
颜色映射规范化

自定义规范化:两个线性范围

可以定义自己的规范化。在下面的示例中,我们修改 colors:SymLogNorm() 对负数据值和正数据使用不同的线性映射。(请注意,此示例很简单,不验证输入或解释复杂情况,如屏蔽数据)

注解

这可能很快就会出现 colors.OffsetNorm() .

如上所述,数据到颜色的非对称映射是定量数据的非标准实践,应谨慎使用。一个实际的例子是有一个海洋/陆地颜色图,其中陆地和海洋数据跨越不同的范围。

N = 100
X, Y = np.mgrid[-3:3:complex(0, N), -2:2:complex(0, N)]
Z1 = np.exp(-X**2 - Y**2)
Z2 = np.exp(-(X - 1)**2 - (Y - 1)**2)
Z = (Z1 - Z2) * 2


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 and all kinds of edge cases to make a
        # 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(2, 1)

pcm = ax[0].pcolormesh(X, Y, Z,
                       norm=MidpointNormalize(midpoint=0.),
                       cmap='RdBu_r')
fig.colorbar(pcm, ax=ax[0], extend='both')

pcm = ax[1].pcolormesh(X, Y, Z, cmap='RdBu_r', vmin=-np.max(Z))
fig.colorbar(pcm, ax=ax[1], extend='both')
fig.show()
颜色映射规范化

脚本的总运行时间: (0分1.832秒)