Python Matplotlib:创建具有特定值白色间隔的正常颜色条
Python Matplotlib: Create normal colorbar with white interval at specific values
我有南极洲周围的海冰浓度数据,范围在 -40 到 +40 之间(见附图),但我希望 +10 到 -10 之间的值在我的地图和颜色栏中显示为白色,因为它们确实如此不代表海冰浓度(它们在当前图中显示为浅绿色和浅蓝色)。
我不想将它们从我的数组中排除,而是想为它们分配特定的颜色(在本例中为白色)并为其他值保留喷气色阶。
我已经查看了其他多个问题(即 How to change colorbar's color (in some particular value interval)?; Python matplotlib change default color for values exceeding colorbar range; **)
但未能将这些应用到我的案例中。
我曾尝试使用 'set under'、'set over'、'set.bad',但未能获得我想要的效果。我也曾尝试创建自己的颜色图,但也没有成功。
有人能帮忙吗?
谢谢。
更新:
我已经修改了 'whosebug.com/a/41815114/5103802' 中的代码(请参阅下面的更新代码)但是我的值 [+10 -10] 和 'jet' 的颜色不是白色
对于高于 +10 和低于 -10(见下图)。 'tmap' 对象似乎弄乱了色阶。关于如何获得 jet colorscale 并在 -10 和 +10 之间留下白色间隔的任何想法?
感谢您的帮助。
更新代码:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors
from mpl_toolkits.basemap import Basemap, cm, rcParams
HIGH_86 = a.variables['high_86'][:]
n=40
x = 10
lower = plt.cm.seismic(np.linspace(1-x, 0, n))
upper = plt.cm.seismic(np.linspace(0, x, n))
white1 = plt.cm.seismic(np.ones(10)*x)
white2 = plt.cm.seismic(np.ones(10)*-(x))
colors = np.vstack((lower, white1, white2, upper))
tmap = matplotlib.colors.LinearSegmentedColormap.from_list('terrain_map_white', colors)
x = HIGH_86
lats = a.variables['latitude'][:]
lons = a.variables['longitude'][:]
lons, lats = np.meshgrid(lons,lats)
fig, ax = plt.subplots()
m2 = Basemap(projection='spstere',boundinglat=-50,lon_0=180,resolution='l')
CS2 = m2.contourf(lons,lats,x,cmap=tmap,latlon=True)
cbar = m2.colorbar(CS2,location='right', pad="12%")
m2.drawparallels(np.arange(-90.,99.,60.),labels=[False,False,False,False])
m2.drawmeridians(np.arange(-180.,180.,90.),labels=[True,False,False,True])
m2.drawcoastlines()
m1.fillcontinents(color='grey')
plt.title('SIE Anomaly')
plt.show()
我假设您已经阅读了 linked question 及其答案。
它明确指出
Colormaps are always ranged between 0 and 1.
并进一步解释了如何获得合适的颜色图。因此,向颜色图提供 10 或 -9 的值是没有意义的。
虽然您可以直接从此处的答案中复制代码并获得不错的结果,但您当然也可以对其进行优化以匹配这种特定情况,其中可以选择 80 种颜色,其中 30 种来自下半部分颜色图,上部 30 个,中间剩余 20 个为白色。
n=30
x = 0.5
lower = plt.cm.seismic(np.linspace(0, x, n))
white = plt.cm.seismic(np.ones(80-2*n)*x)
upper = plt.cm.seismic(np.linspace(1-x, 1, n))
colors = np.vstack((lower, white, upper))
tmap = matplotlib.colors.LinearSegmentedColormap.from_list('map_white', colors)
为了得到其中没有白色的jet colormap,可以在中间使用一个数组
n=30
x = 0.5
cmap = plt.cm.jet
lower = cmap(np.linspace(0, x, n))
white = np.ones((80-2*n,4))
upper = cmap(np.linspace(1-x, 1, n))
colors = np.vstack((lower, white, upper))
tmap = matplotlib.colors.LinearSegmentedColormap.from_list('map_white', colors)
重现上图的完整代码:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors
n=30
x = 0.5
cmap = plt.cm.jet
lower = cmap(np.linspace(0, x, n))
white = np.ones((80-2*n,4))
upper = cmap(np.linspace(1-x, 1, n))
colors = np.vstack((lower, white, upper))
tmap = matplotlib.colors.LinearSegmentedColormap.from_list('map_white', colors)
x = np.linspace(0,10)
X,Y = np.meshgrid(x,x)
z = np.sin(X) * np.cos(Y*0.4)*40
fig, ax = plt.subplots()
im = ax.contourf(z, cmap=tmap, vmin=-40, vmax=40)
plt.colorbar(im)
plt.show()
我有南极洲周围的海冰浓度数据,范围在 -40 到 +40 之间(见附图),但我希望 +10 到 -10 之间的值在我的地图和颜色栏中显示为白色,因为它们确实如此不代表海冰浓度(它们在当前图中显示为浅绿色和浅蓝色)。
我不想将它们从我的数组中排除,而是想为它们分配特定的颜色(在本例中为白色)并为其他值保留喷气色阶。
我已经查看了其他多个问题(即 How to change colorbar's color (in some particular value interval)?; Python matplotlib change default color for values exceeding colorbar range; **
但未能将这些应用到我的案例中。
我曾尝试使用 'set under'、'set over'、'set.bad',但未能获得我想要的效果。我也曾尝试创建自己的颜色图,但也没有成功。
有人能帮忙吗?
谢谢。
更新:
我已经修改了 'whosebug.com/a/41815114/5103802' 中的代码(请参阅下面的更新代码)但是我的值 [+10 -10] 和 'jet' 的颜色不是白色 对于高于 +10 和低于 -10(见下图)。 'tmap' 对象似乎弄乱了色阶。关于如何获得 jet colorscale 并在 -10 和 +10 之间留下白色间隔的任何想法?
感谢您的帮助。
更新代码:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors
from mpl_toolkits.basemap import Basemap, cm, rcParams
HIGH_86 = a.variables['high_86'][:]
n=40
x = 10
lower = plt.cm.seismic(np.linspace(1-x, 0, n))
upper = plt.cm.seismic(np.linspace(0, x, n))
white1 = plt.cm.seismic(np.ones(10)*x)
white2 = plt.cm.seismic(np.ones(10)*-(x))
colors = np.vstack((lower, white1, white2, upper))
tmap = matplotlib.colors.LinearSegmentedColormap.from_list('terrain_map_white', colors)
x = HIGH_86
lats = a.variables['latitude'][:]
lons = a.variables['longitude'][:]
lons, lats = np.meshgrid(lons,lats)
fig, ax = plt.subplots()
m2 = Basemap(projection='spstere',boundinglat=-50,lon_0=180,resolution='l')
CS2 = m2.contourf(lons,lats,x,cmap=tmap,latlon=True)
cbar = m2.colorbar(CS2,location='right', pad="12%")
m2.drawparallels(np.arange(-90.,99.,60.),labels=[False,False,False,False])
m2.drawmeridians(np.arange(-180.,180.,90.),labels=[True,False,False,True])
m2.drawcoastlines()
m1.fillcontinents(color='grey')
plt.title('SIE Anomaly')
plt.show()
我假设您已经阅读了 linked question 及其答案。 它明确指出
Colormaps are always ranged between 0 and 1.
并进一步解释了如何获得合适的颜色图。因此,向颜色图提供 10 或 -9 的值是没有意义的。
虽然您可以直接从此处的答案中复制代码并获得不错的结果,但您当然也可以对其进行优化以匹配这种特定情况,其中可以选择 80 种颜色,其中 30 种来自下半部分颜色图,上部 30 个,中间剩余 20 个为白色。
n=30
x = 0.5
lower = plt.cm.seismic(np.linspace(0, x, n))
white = plt.cm.seismic(np.ones(80-2*n)*x)
upper = plt.cm.seismic(np.linspace(1-x, 1, n))
colors = np.vstack((lower, white, upper))
tmap = matplotlib.colors.LinearSegmentedColormap.from_list('map_white', colors)
为了得到其中没有白色的jet colormap,可以在中间使用一个数组
n=30
x = 0.5
cmap = plt.cm.jet
lower = cmap(np.linspace(0, x, n))
white = np.ones((80-2*n,4))
upper = cmap(np.linspace(1-x, 1, n))
colors = np.vstack((lower, white, upper))
tmap = matplotlib.colors.LinearSegmentedColormap.from_list('map_white', colors)
重现上图的完整代码:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors
n=30
x = 0.5
cmap = plt.cm.jet
lower = cmap(np.linspace(0, x, n))
white = np.ones((80-2*n,4))
upper = cmap(np.linspace(1-x, 1, n))
colors = np.vstack((lower, white, upper))
tmap = matplotlib.colors.LinearSegmentedColormap.from_list('map_white', colors)
x = np.linspace(0,10)
X,Y = np.meshgrid(x,x)
z = np.sin(X) * np.cos(Y*0.4)*40
fig, ax = plt.subplots()
im = ax.contourf(z, cmap=tmap, vmin=-40, vmax=40)
plt.colorbar(im)
plt.show()