Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 非线性彩色映射_Python_Matplotlib - Fatal编程技术网

Python 非线性彩色映射

Python 非线性彩色映射,python,matplotlib,Python,Matplotlib,是否有任何颜色贴图,或者是否有一种简单的方法来转换matplotlib颜色贴图,以提供更大的接近0.5的颜色范围,并在极端情况下提供更小的颜色范围?我正在创建一组子图,其中一个的颜色值大约是其他的10倍,所以它的值占主导地位,其余的图看起来都一样。举个简单的例子,我们有: import numpy as np import matplotlib.pyplot as plt x = np.linspace(1,10,10) y = np.linspace(1,10,10) t1 = np.ra

是否有任何颜色贴图,或者是否有一种简单的方法来转换matplotlib颜色贴图,以提供更大的接近0.5的颜色范围,并在极端情况下提供更小的颜色范围?我正在创建一组子图,其中一个的颜色值大约是其他的10倍,所以它的值占主导地位,其余的图看起来都一样。举个简单的例子,我们有:

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(1,10,10)
y = np.linspace(1,10,10)

t1 = np.random.normal(2,0.3,10)
t2 = np.random.normal(9,0.01,10)
t2_max = max(t2)

plt.figure(figsize=(22.0, 15.50))

p = plt.subplot(1,2,1)
colors = plt.cm.Accent(t1/t2_max)
p.scatter(x, y, edgecolors=colors, s=15, linewidths=4)

p = plt.subplot(1,2,2)
colors = plt.cm.Accent(t2/t2_max)
p.scatter(x, y, edgecolors=colors, s=15, linewidths=4)

plt.subplots_adjust(left=0.2)
cbar_ax = plt.axes([0.10, 0.15, 0.05, 0.7])
sm = plt.cm.ScalarMappable(cmap=plt.cm.Accent, norm=plt.Normalize(vmin=0, vmax=t2_max))
sm._A = []
cbar = plt.colorbar(sm,cax=cbar_ax)

plt.show()
t1的变异比t2的变异大得多,但由于t2的高值,无法看到这种变异。我想要的是一张地图,它将在t1的平均值周围提供一个更大的颜色梯度,而无需转换数据本身。我在这里找到了一个解决方案,但无法使其适用于我的散点图

编辑: 从下面的答案类可以修改为负数,并固定边界

import numpy as np
import matplotlib.pyplot as plt

x = y = np.linspace(1, 10, 10)

t1mean, t2mean = -6, 9
sigma1, sigma2 = .3, .01
t1 = np.random.normal(t1mean, sigma1, 10)
t2 = np.random.normal(t2mean, sigma2, 10)

class nlcmap(object):
    def __init__(self, cmap, levels):
        self.cmap = cmap
        self.N = cmap.N
        self.monochrome = self.cmap.monochrome
        self.levels = np.asarray(levels, dtype='float64')
        self._x = self.levels
        self.levmax = self.levels.max()
        self.levmin = self.levels.min()
        self.transformed_levels = np.linspace(self.levmin, self.levmax,
             len(self.levels))

    def __call__(self, xi, alpha=1.0, **kw):
        yi = np.interp(xi, self._x, self.transformed_levels)
        return self.cmap(yi / (self.levmax-self.levmin)+0.5, alpha)

tmax = 10
tmin = -10
#the choice of the levels depends on the data:
levels = np.concatenate((
    [tmin, tmax],
    np.linspace(t1mean - 2 * sigma1, t1mean + 2 * sigma1, 5),
    np.linspace(t2mean - 2 * sigma2, t2mean + 2 * sigma2, 5),
    ))
levels = levels[levels <= tmax]
levels.sort()
print levels
cmap_nonlin = nlcmap(plt.cm.jet, levels)

fig, (ax1, ax2) = plt.subplots(1, 2)

ax1.scatter(x, y, edgecolors=cmap_nonlin(t1), s=15, linewidths=4)
ax2.scatter(x, y, edgecolors=cmap_nonlin(t2), s=15, linewidths=4)

fig.subplots_adjust(left=.25)
cbar_ax = fig.add_axes([0.10, 0.15, 0.05, 0.7])

#for the colorbar we map the original colormap, not the nonlinear one:
sm = plt.cm.ScalarMappable(cmap=plt.cm.jet, 
                norm=plt.Normalize(vmin=tmin, vmax=tmax))
sm._A = []

cbar = fig.colorbar(sm, cax=cbar_ax)
#here we are relabel the linear colorbar ticks to match the nonlinear ticks
cbar.set_ticks(cmap_nonlin.transformed_levels)
cbar.set_ticklabels(["%.2f" % lev for lev in levels])

plt.show()
将numpy导入为np
将matplotlib.pyplot作为plt导入
x=y=np.linspace(1,10,10)
t1mean,t2mean=-6,9
sigma1,sigma2=.3,.01
t1=np.随机.正常(t1平均值,sigma1,10)
t2=np.随机.正常(t2平均值,sigma2,10)
类nlcmap(对象):
定义初始(自我、cmap、级别):
self.cmap=cmap
self.N=cmap.N
self.monochy=self.cmap.monochy
self.levels=np.asarray(levels,dtype='float64')
self.\u x=self.levels
self.levmax=self.levels.max()
self.levmin=self.levels.min()
self.transformed_levels=np.linspace(self.levmin,self.levmax,
len(自我水平))
DEF-αCall(自,席,α= 1,**KW):
yi=np.interp(xi,self.\ux,self.transformed\u层级)
返回self.cmap(yi/(self.levmax self.levmin)+0.5,alpha)
tmax=10
tmin=-10
#级别的选择取决于数据:
级别=np.concatenate((
[tmin,tmax],
np.linspace(t1mean-2*sigma1,t1mean+2*sigma1,5),
np.linspace(t2mean-2*sigma2,t2mean+2*sigma2,5),
))
级别=级别[levels你的颜色图提供了一个很好的解决方案。我编辑了一点,但它包含了所有必要的内容。你需要为你的非线性颜色图选择一些合理的级别。我使用了两个以平均值为中心的范围,在样本的标准偏差
+-4
之间。通过将其更改为另一个数字,你可以得到一个d两个平均值周围颜色的不同局部梯度

对于颜色条,您可以

  • 或者将颜色与线性间隔标签保持非线性间隔
  • 您可以使用具有非线性间隔标签的线性间隔颜色
第二种方法在查看数据时具有更高的分辨率,看起来更漂亮,具体实现如下:

import numpy as np
import matplotlib.pyplot as plt

x = y = np.linspace(1, 10, 10)

t1mean, t2mean = 2, 9
sigma1, sigma2 = .3, .01
t1 = np.random.normal(t1mean, sigma1, 10)
t2 = np.random.normal(t2mean, sigma2, 10)

class nlcmap(object):
    def __init__(self, cmap, levels):
        self.cmap = cmap
        self.N = cmap.N
        self.monochrome = self.cmap.monochrome
        self.levels = np.asarray(levels, dtype='float64')
        self._x = self.levels
        self.levmax = self.levels.max()
        self.transformed_levels = np.linspace(0.0, self.levmax,
             len(self.levels))

    def __call__(self, xi, alpha=1.0, **kw):
        yi = np.interp(xi, self._x, self.transformed_levels)
        return self.cmap(yi / self.levmax, alpha)

tmax = max(t1.max(), t2.max())
#the choice of the levels depends on the data:
levels = np.concatenate((
    [0, tmax],
    np.linspace(t1mean - 4 * sigma1, t1mean + 4 * sigma1, 5),
    np.linspace(t2mean - 4 * sigma2, t2mean + 4 * sigma2, 5),
    ))

levels = levels[levels <= tmax]
levels.sort()

cmap_nonlin = nlcmap(plt.cm.jet, levels)

fig, (ax1, ax2) = plt.subplots(1, 2)

ax1.scatter(x, y, edgecolors=cmap_nonlin(t1), s=15, linewidths=4)
ax2.scatter(x, y, edgecolors=cmap_nonlin(t2), s=15, linewidths=4)

fig.subplots_adjust(left=.25)
cbar_ax = fig.add_axes([0.10, 0.15, 0.05, 0.7])

#for the colorbar we map the original colormap, not the nonlinear one:
sm = plt.cm.ScalarMappable(cmap=plt.cm.jet, 
                norm=plt.Normalize(vmin=0, vmax=tmax))
sm._A = []

cbar = fig.colorbar(sm, cax=cbar_ax)
#here we are relabel the linear colorbar ticks to match the nonlinear ticks
cbar.set_ticks(cmap_nonlin.transformed_levels)
cbar.set_ticklabels(["%.2f" % lev for lev in levels])

plt.show()
将numpy导入为np
将matplotlib.pyplot作为plt导入
x=y=np.linspace(1,10,10)
t1平均值,t2平均值=2,9
sigma1,sigma2=.3,.01
t1=np.随机.正常(t1平均值,sigma1,10)
t2=np.随机.正常(t2平均值,sigma2,10)
类nlcmap(对象):
定义初始(自我、cmap、级别):
self.cmap=cmap
self.N=cmap.N
self.monochy=self.cmap.monochy
self.levels=np.asarray(levels,dtype='float64')
self.\u x=self.levels
self.levmax=self.levels.max()
self.transformed_levels=np.linspace(0.0,self.levmax,
len(自我水平))
DEF-αCall(自,席,α= 1,**KW):
yi=np.interp(xi,self.\ux,self.transformed\u层级)
返回self.cmap(yi/self.levmax,alpha)
tmax=max(t1.max(),t2.max())
#级别的选择取决于数据:
级别=np.concatenate((
[0,tmax],
np.linspace(t1mean-4*sigma1,t1mean+4*sigma1,5),
np.linspace(t2mean-4*sigma2,t2mean+4*sigma2,5),
))
levels=levels[levels您可以使用:

这样,您需要在字典中设置颜色查找表,例如下面的“cdict”

cdict = {'red':   [(0.0,  0.0, 0.0),
                   (0.15,  0.01, 0.01),
                   (0.35,  1.0, 1.0),
                   (1.0,  1.0, 1.0)],

         'green': [(0.0,  0.0, 0.0),
                   (1.0,  0.0, 1.0)],

         'blue':  [(0.0,  0.0, 1.0),
                   (0.9,  0.01, 0.01),
                   (1.0,  0.0, 1.0)]}
这显示了值之间的转换。我已将红色设置为围绕
t1/t2_max
(0.15到0.35)的值变化很大,将蓝色设置为围绕
t2/t2_max
(0.9到1.0)的值变化很大。绿色不起任何作用。我建议阅读以了解其工作原理。(请注意,这可以自动改变您的值)。然后我调整了您的代码以显示图形:

import matplotlib.colors as col

my_cmap = col.LinearSegmentedColormap('my_colormap', cdict)

plt.figure(figsize=(22.0, 15.50))

p = plt.subplot(1,2,1)
colors = my_cmap(t1/t2_max)

p.scatter(x, y, edgecolors=colors, s=15, linewidths=4)

p = plt.subplot(1,2,2)
colors = my_cmap(t2/t2_max)

p.scatter(x, y, edgecolors=colors, s=15, linewidths=4)

plt.subplots_adjust(left=0.2)
cbar_ax = plt.axes([0.10, 0.15, 0.05, 0.7])
sm = plt.cm.ScalarMappable(cmap=my_cmap, norm=plt.Normalize(vmin=0, vmax=t2_max))
sm._A = []
cbar = plt.colorbar(sm,cax=cbar_ax)

plt.show()

你试过
norm=colors.LogNorm
吗?我试过,但没法成功。我一直在努力解决颜色映射问题。你介意修改上面的示例来展示它是如何工作的吗?谢谢,效果很好。不过,我还是不太明白cmap是如何工作的,如果有人能浏览并评论一下这个类的工作原理,那就太好了。有关负数和固定边界的版本,请参见“编辑”。好的,但您必须具体说明。您能告诉我哪一行很难理解,哪些内容不清楚吗?