位移的色条matplotlib

30

我试图为一个数据集创建填充等高线图。这应该是相当直接的:

plt.contourf(x, y, z, label = 'blah', cm = matplotlib.cm.RdBu)

然而,如果我的数据集关于0不对称,我该怎么办?假设我想从蓝色(负值)到0(白色),再到红色(正值)。如果我的数据集范围从-8到3,那么颜色条的白色部分应该在0处,实际上是稍微负一些。有没有办法移动颜色条?

1个回答

54

首先,有不止一种方法可以实现此目的。

  1. DivergingNorm 的实例作为 norm 参数传递。
  2. 使用 colors 参数来调用 contourf 并手动指定颜色。
  3. 使用由 matplotlib.colors.from_levels_and_colors 构建的离散 colormap。

最简单的方法是第一种选项。这也是唯一允许您使用连续colormap的选项。

选择第一或第三种选项的原因是它们适用于使用colormap的任何类型的 matplotlib 绘图(例如 imshow, scatter 等)。

第三个选项基于特定颜色构造一个离散的colormap和规范化对象。它与第二种选项基本相同,但它将会 a) 适用于除等高线图之外的其他类型的绘图,b) 避免手动指定轮廓线数量。

以下是第一个选项的示例(我将在此处使用 imshow,因为对于随机数据来说比 contourf 更有意义,但除了 interpolation 选项外,contourf 的用法完全相同):

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

data = np.random.random((10,10))
data = 10 * (data - 0.8)

fig, ax = plt.subplots()
im = ax.imshow(data, norm=DivergingNorm(0), cmap=plt.cm.seismic, interpolation='none')
fig.colorbar(im)
plt.show()

第一个选项结果

作为第三个选项的示例(请注意,这将提供离散的颜色图而不是连续的颜色图):

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

data = np.random.random((10,10))
data = 10 * (data - 0.8)

num_levels = 20
vmin, vmax = data.min(), data.max()
midpoint = 0
levels = np.linspace(vmin, vmax, num_levels)
midp = np.mean(np.c_[levels[:-1], levels[1:]], axis=1)
vals = np.interp(midp, [vmin, midpoint, vmax], [0, 0.5, 1])
colors = plt.cm.seismic(vals)
cmap, norm = from_levels_and_colors(levels, colors)

fig, ax = plt.subplots()
im = ax.imshow(data, cmap=cmap, norm=norm, interpolation='none')
fig.colorbar(im)
plt.show()

第三个选项的结果


4
应该添加到Matplotlib。 - Moritz
@Joe Kington,太棒了!我正在将你的类定义复制到一个开源项目中,并将你的名字作为作者。希望你没有意见。 - Asif Rehan
1
@user832 - 加油!然而,Paul Hobson最近在mpl的pull request中提供了一个更完整的版本,与同一通用事物相同:https://github.com/matplotlib/matplotlib/pull/3858 根据您需要的功能,您可能最好基于那个版本。 - Joe Kington
1
正如@JoeKington上面提到的,MidpointNormalize无法处理许多边缘情况。我需要一个解决方案,它可以使用一个包含所有零的起始数组,然后随着时间的推移更新值。最终我采用了来自https://github.com/matplotlib/matplotlib/pull/5054的DivergingNorm来处理这种情况。显然,这个问题的强大解决方案已经非常困难,因此开发已经不再进行。这似乎很奇怪,因为在使用具有正负数据的分歧调色板时,将0设置为中心点是一个常见的用例。 - Todd Johnson
2
对于今天使用这个很棒的答案的任何人,需要注意的是,DivergingNorm在3.2版本之后已被重命名为TwoSlopeNorm,而DivergingNorm现在已经被弃用。 - Ryan Ward
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接