假设我有这样的数据:
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()
给出了
我遇到的问题是现在看起来这些数据是相同的,尽管右边的值是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
如果是的话,怎么会这样做?
答案 0 :(得分:2)
matplotlib色彩映射将0到1之间的数值范围映射到一系列颜色。
如果数据范围超过[0,1]以外的时间间隔(当然几乎总是如此),则首先将该范围标准化为该间隔。此标准化由使用中的ScalarMappable在内部完成(例如,在这种情况下为散点图)。
在需要自定义规范化的情况下,如同两个不同的绘图需要共享颜色编码时,可以在创建ScalarMappable时指定。
使用vmin
和vmax
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))