非线性色图/热图

3
我试图为一种基因制作一个一维热力图(参见pastebin中的ref 1示例)。使用contourf,我已经接近我想要的结果,但我还没有能够弄清楚如何得到我想要的确切结果。基本上,我想利用一个具有10个离散颜色的颜色映射,不同颜色的截止值对应于数据的百分位数(因此数据点的前10%为红色,下一个10%为橙色等)。
我没有足够的声誉来发布超过两个链接或任何图像,因此您也可以在http://pastebin.com/jAkxyQsK中查看我的输出图像以及我查看解决此问题的其他页面。
实际数据点在http://pastebin.com/3TrkkpZ0的列表中。您可以尝试随机整数,但是除非您的数据偏斜像我的那样,否则线性缩放和百分位缩放之间的差异可能不明显。
data = [] #actually a list of ~450 floats 
x = []
nd = np.array(data)
x = np.empty([2, nd.shape[0]])
x[:,:] = nd

fig = plt.figure(figsize = (11, 8.5))
ax = fig.add_subplot(111)

现在,这是我的实验:
mind, maxd, sprd = min(data), max(data), max(data)-min(data)
levels = [(lambda n: mind + (n*sprd)/10)(n) for n in range(0,11,1)]
hm = plt.contourf(x, levels = levels, cmap = "rainbow")
cbar = fig.colorbar(hm, ax = ax)
plt.show()

[在pastebin上的图1]

这基本上是我想要看到的:色条被离散化,绘图看起来不错,但是色条在数据的最大值和最小值之间线性分布,这不是我想要的。第二次尝试:

levels = np.percentile(data, [z for z in range (0,110,10)])
hm = plt.contourf(x, levels = levels, cmap = "rainbow")
cbar = fig.colorbar(hm, ax = ax)
plt.show()

[pastebin上的图2]

这也很接近了;色条按百分位数值划分(或者至少刻度值表明如此),但由于某种原因它不再利用完整的颜色映射范围,我不知道为什么。

我还尝试使用参考文献2和3中描述的函数来实现pcolor,但我无法弄清楚如何使它们适用于我的数据而不是散点图,并且结果与contourf相比不够接近,因此我停止了追求。如果答案已经在我查看的链接中,但我无法理解它,那么“通俗易懂”的翻译将非常有帮助。

1个回答

1
我无法确定为什么在你的示例中调色板没有使用完整的颜色范围,但似乎以下内容更接近你想要的结果(即它使用分位数级别跨越了更大的颜色范围)。
...
hm = plt.contourf(x, levels = levels, cmap = "rainbow", vmax = levels[-2])
...

您也可以尝试使用“加权”值来设置最大的颜色映射级别。

...
hm = plt.contourf(x, levels = levels, cmap = "rainbow", vmax = 0.3 * levels[-1] + 0.7 * levels[-2])
...

谢谢您的建议 - 我认为第一个建议基本上是我正在寻找的,但是老实说,我不知道它为什么有效。您能解释一下vmax在做什么吗? - Emmett
嗨 - 当您没有明确提供时,vmax的值是数据的最大值,并且它使用颜色映射的高端颜色谱进行着色。例如,对于颜色映射“彩虹”,vmax被映射为红色。当您将vmax设置为较低的值时,您就是在说应该使用颜色谱(对于'rainbow'是红色)的高端来着色所有至少与您的vmax一样高的数据值。 - michalis

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