色彩图的非线性缩放以增强对比度 [英] Non-linear scaling of a colormap to enhance contrast
问题描述
以下 python 代码创建包含正态分布值的矩阵的热图
The following python code creates a heatmap of a matrix that contains normally distributed values
import numpy as np
from matplotlib import pylab as plt
np.random.seed(123) #make sure we all have same data
m = np.random.randn(200).reshape(10, 20)
plt.imshow(m, cmap='RdYlGn', interpolation='nearest')
plt.colorbar()
这是这段代码的输出
我想通过淡入"接近零的值来增强此图像的对比度.我可以通过如下方式对原始数据进行双曲线缩放来轻松实现此目的:
I would like to enhance the contrast of this image by "fading out" the values close to zero. I can easily do this by using disigmoid scaling of the original data as follows:
def disigmoidScaling(values, steepnessFactor=1, ref=None):
''' Sigmoid scaling in which values around a reference point are flattened
arround a reference point
Scaled value y is calculated as
y = sign(v - d)(1 - exp(-((x - d)/s)**2)))
where v is the original value, d is the referenc point and s is the
steepness factor
'''
if ref is None:
mn = np.min(values)
mx = np.max(values)
ref = mn + (mx - mn) / 2.0
sgn = np.sign(values - ref)
term1 = ((values - ref)/steepnessFactor) ** 2
term2 = np.exp(- term1)
term3 = 1.0 - term2
return sgn * term3
plt.imshow(disigmoidScaling(m, 4), cmap='RdYlGn', interpolation='nearest')
plt.colorbar()
这是输出.
我对结果很满意,除了在这个版本中原来的值已交换为缩放值.
I'm pleased with the result, except the fact that in this version the original values have been exchanged for scaled ones.
有没有办法将值非线性映射到颜色图?
Is there a way to perform a non-linear mapping of values to colormap?
推荐答案
颜色表包含在间隔[0,1]上映射的红色,绿色和蓝色值的字典.Linear Segmented Colormap 类文档给出了示例
A colormap contains a dictionary of red, green and blue values mapped over the interval [0,1]. The Linear Segmented Colormap class docs give the example
cdict = {'red': [(0.0, 0.0, 0.0),
(0.5, 1.0, 1.0),
(1.0, 1.0, 1.0)],
'green': [(0.0, 0.0, 0.0),
(0.25, 0.0, 0.0),
(0.75, 1.0, 1.0),
(1.0, 1.0, 1.0)],
'blue': [(0.0, 0.0, 0.0),
(0.5, 0.0, 0.0),
(1.0, 1.0, 1.0)]}
表中给定颜色的每一行都是一个x,y0,y1元组的序列.在每个序列中,x必须从0到1单调递增.对于任何介于x [i]和x之间的输入值z[i+1],给定颜色的输出值将在 y1[i] 和 y0[i+1] 之间进行线性插值:"
"Each row in the table for a given color is a sequence of x, y0, y1 tuples. In each sequence, x must increase monotonically from 0 to 1. For any input value z falling between x[i] and x[i+1], the output value of a given color will be linearly interpolated between y1[i] and y0[i+1]:"
RdYlGn
颜色图具有11个值,每种颜色从0到1.0的步长为0.1.您可以通过调用
The RdYlGn
colormap has 11 x values for each color going from 0 to 1.0 in steps of 0.1. You can get the cdict
values by calling
plt.cm.RdYlGn._segmentdata
然后您可以将x值更改为所需的任何步长(只要它们单调递增且范围从0到1),并通过调用 matplotlib.colors.LinearSegmentedColormap
获得新的颜色图.您的新 cdict
.Matplotlib Cookbook 中有几个很好的例子.
You can then change the x values to whatever steps you want (as long as they are monotonically increasing and range from 0 to 1) and get a new colormap by calling matplotlib.colors.LinearSegmentedColormap
on your new cdict
. There are several great examples of this in the Matplotlib Cookbook.
这篇关于色彩图的非线性缩放以增强对比度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!