如何创建自定义色彩映射并将其用于不同的数据范围?

时间:2017-12-07 14:54:56

标签: python matplotlib colors colormap

假设我有这样的数据:

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

# for reproducibility purposes
np.random.seed(0)

# generate some data
n = 30
x = np.array(range(n))

a1 = np.random.rand(n)
a2 = a1 * 100

我想在两个子图中绘制这些数据,我可以做(this answer的变体)

cmap = matplotlib.colors.LinearSegmentedColormap.from_list("", [(0., '#9696ff'), (0.2, '#f0ffff'), (1.0, '#ff0000')])

fig, (ax1, ax2) = plt.subplots(1, 2)
ax1.scatter(x, a1, c=a1, cmap=cmap)
ax2.scatter(x, a2, c=a2, cmap=cmap)
plt.show()

给出了

enter image description here

我遇到的问题是现在看起来这些数据是相同的,尽管右边的值是100倍。

所以,我想要的是一个色彩图,我可以用于两个图;而不是

matplotlib.colors.LinearSegmentedColormap.from_list("", [(0., '#9696ff'), (0.2, '#f0ffff'), (1.0, '#ff0000')])

我想使用像

这样的东西
min_a1_a2 = min(min(a1), min(a2))
max_a1_a2 = max(max(a1), max(a2))
cmap = matplotlib.colors.LinearSegmentedColormap.from_list("", [(min_a1_a2, '#9696ff'), ((min_a1_a2 + max_a1_a2) / 2., '#f0ffff'), (max_a1_a2, '#ff0000')])

但这总是会导致错误

  

ValueError:数据映射点必须以x = 0开头。并以x = 1

结束

当我将其传递给scatter时(使用与上面相同的命令)。

有没有办法将任意(值,颜色)元组传递给matplotlib.colors.LinearSegmentedColormap.from_list,然后将生成的颜色映射传递给scatter如果是的话,怎么会这样做?

1 个答案:

答案 0 :(得分:2)

matplotlib色彩映射将0到1之间的数值范围映射到一系列颜色。

如果数据范围超过[0,1]以外的时间间隔(当然几乎总是如此),则首先将该范围标准化为该间隔。此标准化由使用中的ScalarMappable在内部完成(例如,在这种情况下为散点图)。

在需要自定义规范化的情况下,如同两个不同的绘图需要共享颜色编码时,可以在创建ScalarMappable时指定。

使用vminvmax

plt.scatter(x,y, c=c, cmap=cmap, vmin=0, vmax=100)

或通过规范化实例

plt.scatter(x,y, c=c, cmap=cmap, norm=plt.Normalize(0,100))