修改matplotlib色彩映射

时间:2018-03-19 15:50:40

标签: python python-3.x matplotlib

我试图使用Python生成此图像的类似版本:

Original Image

我已经关闭,但无法弄清楚如何修改matplotlib色彩图以使值<0.4变为白色。我试图屏蔽这些值并使用set_bad,但我最终得到了一个真实的块状外观,失去了原始图像中看到的漂亮流畅的轮廓。

  • 连续色图的结果(问题:无白色):

    Image with all colors

  • set_bad的结果(问题:没有平滑过渡到白色):

    Image with masked values

到目前为止

代码:

from netCDF4 import Dataset as NetCDFFile
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.basemap import Basemap
nc = NetCDFFile('C:/myfile1.nc')
nc1 = NetCDFFile('C:/myfile2.nc')
lat = nc.variables['lat'][:]
lon = nc.variables['lon'][:]
time = nc.variables['time'][:]
uwnd = nc.variables['uwnd'][:]
vwnd = nc1.variables['vwnd'][:]
map = Basemap(llcrnrlon=180.,llcrnrlat=0.,urcrnrlon=340.,urcrnrlat=80.)
lons,lats = np.meshgrid(lon,lat)
x,y = map(lons,lats)
speed = np.sqrt(uwnd*uwnd+vwnd*vwnd)
#speed = np.ma.masked_where(speed < 0.4, speed)
#cmap = plt.cm.jet
#cmap.set_bad(color='white')
levels = np.arange(0.0,3.0,0.1)
ticks = np.arange(0.0,3.0,0.2)
cs = map.contourf(x,y,speed[0],levels, cmap='jet')
vw = plt.quiver(x,y,speed)
cbar = plt.colorbar(cs, orientation='horizontal', cmap='jet', spacing='proportional',ticks=ticks)
cbar.set_label('850 mb Vector Wind Anomalies (m/s)')
map.drawcoastlines()
map.drawparallels(np.arange(20,80,20),labels=[1,1,0,0], linewidth=0.5)
map.drawmeridians(np.arange(200,340,20),labels=[0,0,0,1], linewidth=0.5)
#plt.show()
plt.savefig('phase8_850wind_anom.png',dpi=600)

1 个答案:

答案 0 :(得分:1)

获得结果平滑的答案在于构建自己的色彩映射表。要做到这一点,必须创建一个RGBA矩阵:一个矩阵,每行包含红色,绿色,蓝色和Alpha的数量(介于0和1之间)(透明度; 0表示像素没有任何覆盖信息,是透明的。)

作为示例,到某个点的距离以二维绘制。然后:

  • 对于任何高于某个临界值的距离,颜色将从标准色图中获取。
  • 对于低于某个临界值的任何距离,颜色将线性地从白色变为前面提到的地图的第一种颜色。
  

选择完全取决于您想要展示的内容。色彩映射及其大小取决于您的问题。例如,您可以选择不同类型的插值:线性,指数,......;单色或多色彩色图;等等。

代码:

import numpy             as np
import matplotlib        as mpl
import matplotlib.pyplot as plt

from mpl_toolkits.axes_grid1 import make_axes_locatable

# create colormap
# ---------------

# create a colormap that consists of
# - 1/5 : custom colormap, ranging from white to the first color of the colormap
# - 4/5 : existing colormap

# set upper part: 4 * 256/4 entries
upper = mpl.cm.jet(np.arange(256))

# set lower part: 1 * 256/4 entries
# - initialize all entries to 1 to make sure that the alpha channel (4th column) is 1
lower = np.ones((int(256/4),4))
# - modify the first three columns (RGB):
#   range linearly between white (1,1,1) and the first color of the upper colormap
for i in range(3):
  lower[:,i] = np.linspace(1, upper[0,i], lower.shape[0])

# combine parts of colormap
cmap = np.vstack(( lower, upper ))

# convert to matplotlib colormap
cmap = mpl.colors.ListedColormap(cmap, name='myColorMap', N=cmap.shape[0])

# show some example
# -----------------

# open a new figure
fig, ax = plt.subplots()

# some data to plot: distance to point at (50,50)
x,y = np.meshgrid(np.linspace(0,99,100),np.linspace(0,99,100))
z   = (x-50)**2. + (y-50)**2.

# plot data, apply colormap, set limit such that our interpretation is correct
im = ax.imshow(z, interpolation='nearest', cmap=cmap, clim=(0,5000))

# add a colorbar to the bottom of the image
div  = make_axes_locatable(ax)
cax  = div.append_axes('bottom', size='5%', pad=0.4)
cbar = plt.colorbar(im, cax=cax, orientation='horizontal')

# save/show the image
plt.savefig('so.png')
plt.show()

结果:

enter image description here