Python matplotlib bwr颜色贴图,始终以零为中心

Python matplotlib bwr颜色贴图,始终以零为中心,python,matplotlib,colors,Python,Matplotlib,Colors,我试图用正数和负数绘制一个矩阵。数字的间隔为-1到1,但不在完整范围内。例如,数字有时可能在-0.2到+0.8之间(参见下面的代码)。 我想使用bwr颜色映射(蓝色->白色-红色),这样零总是用白色编码的-1应以最深的蓝色进行颜色编码,+1应以最深的红色进行颜色编码。下面是一个示例,其中两个图都只能通过颜色条进行区分 import numpy from matplotlib import pyplot as plt # some arbitrary data to plot x = numpy

我试图用正数和负数绘制一个矩阵。数字的间隔为-1到1,但不在完整范围内。例如,数字有时可能在-0.2到+0.8之间(参见下面的代码)。 我想使用bwr颜色映射(蓝色->白色-红色),这样零总是用白色编码的-1应以最深的蓝色进行颜色编码,+1应以最深的红色进行颜色编码。下面是一个示例,其中两个图都只能通过颜色条进行区分

import numpy
from matplotlib import pyplot as plt

# some arbitrary data to plot
x = numpy.linspace(0, 2*numpy.pi, 30)
y = numpy.linspace(0, 2*numpy.pi, 20)
[X, Y] = numpy.meshgrid(x, y)
Z = numpy.sin(X)*numpy.cos(Y)

fig = plt.figure()
plt.ion()
plt.set_cmap('bwr') # a good start: blue to white to red colormap

# a plot ranging from -1 to 1, hence the value 0 (the average) is colorcoded in white
ax = fig.add_subplot(1, 2, 1)
plt.pcolor(X, Y, Z)
plt.colorbar()

# a plot ranging from -0.2 to 0.8 hence 0.3 (the average) is colorcoded in white
ax = fig.add_subplot(1, 2, 2)
plt.pcolor(X, Y, Z*0.5 + 0.3)   # rescaled Z-Data
plt.colorbar()
由该代码创建的图可以在此处看到:

如上所述,我正在寻找一种方法来始终使用相同的颜色对值进行颜色编码,其中-1:深蓝色、0:白色、+1:深红色。这是一行,我遗漏了什么,还是我必须自己写点什么

编辑: 经过长时间的挖掘,我自己找到了一个令人满意的答案,没有触摸颜色贴图,而是使用可选的输入到
pcolor
(见下文)。
尽管如此,我不会删除该问题,因为在发布此问题并单击相关问题/答案之前,我无法在SO上找到答案。另一方面,我不介意它被删除,因为如果你正在寻找正确的关键词,这个问题的答案可以在别处找到。

显然,我自己在挖掘了一段时间后找到了答案
pcolor
提供可选输入
vmin
vmax
。如果我将它们分别设置为-1和1,那么问题就迎刃而解了。然后,颜色编码似乎与vmin和vmax有关,而不是与绘制的数据的最小值和最大值有关。因此,将plot命令(和注释)更改为

它根据我的需要生成一个图形:


因此,设置
vmin=-1,vmax=1
就可以了,我不必更改颜色映射本身的内容。

您还可以使用
matplotlib.colors
将数据标准化为0作为中点,以增强图形的最大值和最小值。有关中的更多信息,您可以查看更多详细信息

导入matplotlib.colors作为颜色
#制定自己的标准的例子。另请参见matplotlib.colors。
#来自Joe Kington:这一条给出了两种不同的线性斜坡:
类中点规格化(颜色.规格化):
定义初始值(self,vmin=None,vmax=None,middpoint=None,clip=False):
self.midpoint=中点
颜色.规格化._初始化__(self,vmin,vmax,clip)
定义调用(self、value、clip=None):
#我忽略了遮罩值和所有类型的边缘情况,以创建一个
#简单的例子。。。
x、 y=[self.vmin,self.middpoint,self.vmax],[0,0.5,1]
返回numpy.ma.masked_数组(numpy.interp(值,x,y))
#####
#从-0.2到0.8的绘图,因此0.3(平均值)以白色进行彩色编码
ax=图添加子批次(1、2、2)
plt.pcolor(X,Y,Z*0.5+0.3,norm=middpointnormalize(middpoint=0))#将中点设置为0
plt.colorbar(extend='min')#在最小值中扩展colorbar
plt.子批次_调整(左=0.125,下=0.1,右=0.9,上=0.95,wspace=0.5,hspace=0.1)#调整子批次
它产生了这个数字:

您可以像这样使用matplotlib.colors.TwoSlopenRM:

# define your scale, with white at zero
vmin = -0.2 
vmax = 0.8
norm = colors.TwoSlopeNorm(vmin=vmin, vcenter=0, vmax=vmax)
在你的例子中

import numpy
from matplotlib import pyplot as plt

# some arbitrary data to plot
x = numpy.linspace(0, 2*numpy.pi, 30)
y = numpy.linspace(0, 2*numpy.pi, 20)
[X, Y] = numpy.meshgrid(x, y)
Z = numpy.sin(X)*numpy.cos(Y)

fig = plt.figure()
plt.ion()
plt.set_cmap('bwr') # a good start: blue to white to red colormap

# a plot ranging from -1 to 1, hence the value 0 (the average) is colorcoded in white
ax = fig.add_subplot(1, 2, 1)
plt.pcolor(X, Y, Z)
plt.colorbar()

# a plot ranging from -0.2 to 0.8 hence 0.3 (the average) is colorcoded in white
ax = fig.add_subplot(1, 2, 2)

# define your scale, with white at zero
vmin = -0.2 
vmax = 0.8
norm = colors.TwoSlopeNorm(vmin=vmin, vcenter=0, vmax=vmax)

plt.pcolor(X, Y, Z, vmin=vmin, vmax=vmax, norm=norm)   
plt.colorbar()
将为您提供:


很高兴你能解决这个问题,但我想指出的是,只有当正范围设置为与负范围相同时,这种方法才会起作用。不过,这个问题有很多答案,这些答案都是很好的解决方法。@a我在寻找问题/答案时没有找到答案。幸运的是,约束条件vmin==-vmax对我的情况是正确的,我完成了这个问题的研究,因为我对结果感到满意。如果我再遇到这个问题,我现在知道在哪里寻找答案了(-)。这只是有点令人沮丧,因为我知道python和python绘图,我知道如何在matlab中解决我的问题…
diversingnorm
被弃用。较新的代码应该使用
TwoSlopeNorm
而不是谢谢你@lanhi,我更新了答案。
import numpy
from matplotlib import pyplot as plt

# some arbitrary data to plot
x = numpy.linspace(0, 2*numpy.pi, 30)
y = numpy.linspace(0, 2*numpy.pi, 20)
[X, Y] = numpy.meshgrid(x, y)
Z = numpy.sin(X)*numpy.cos(Y)

fig = plt.figure()
plt.ion()
plt.set_cmap('bwr') # a good start: blue to white to red colormap

# a plot ranging from -1 to 1, hence the value 0 (the average) is colorcoded in white
ax = fig.add_subplot(1, 2, 1)
plt.pcolor(X, Y, Z)
plt.colorbar()

# a plot ranging from -0.2 to 0.8 hence 0.3 (the average) is colorcoded in white
ax = fig.add_subplot(1, 2, 2)

# define your scale, with white at zero
vmin = -0.2 
vmax = 0.8
norm = colors.TwoSlopeNorm(vmin=vmin, vcenter=0, vmax=vmax)

plt.pcolor(X, Y, Z, vmin=vmin, vmax=vmax, norm=norm)   
plt.colorbar()