简体   繁体   English

修改matplotlib颜色图

[英]Modify matplotlib colormap

I'm trying to produce a similar version of this image using Python: 我正在尝试使用Python生成此图像的类似版本:

原始图片

I'm close but can't quite figure out how to modify a matplotlib colormap to make values <0.4 go to white. 我已经接近了,但还不太清楚如何修改matplotlib颜色图以使<0.4的值变为白色。 I tried masking those values and using set_bad but I ended up with a real blocky appearance, losing the nice smooth contours seen in the original image. 我尝试掩盖这些值并使用set_bad但最终却出现了块状外观,失去了原始图像中看到的漂亮平滑轮廓。

  • Result with continuous colormap (problem: no white): 连续色图的结果(问题:无白色):

    所有颜色的图像

  • Result with set_bad (problem: no smooth transition to white): set_bad结果(问题:无法顺利过渡到白色):

    具有遮罩值的图像

Code so far: 到目前为止的代码:

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)

The answer to get the result smooth lies in constructing your own colormap. 使结果平滑的答案在于构造自己的颜色图。 To do this one has to create an RGBA-matrix: a matrix with on each row the amount (between 0 and 1) of Red, Green, Blue, and Alpha (transparency; 0 means that the pixel does not have any coverage information and is transparent). 为此,必须创建一个RGBA矩阵:一个矩阵,每行上的红色,绿色,蓝色和Alpha(透明度)的量(介于0和1之间); 0表示像素没有任何覆盖率信息,并且是透明的)。

As an example the distance to some point is plotted in two dimensions. 例如,到某个点的距离以二维绘制。 Then: 然后:

  • For any distance higher than some critical value, the colors will be taken from a standard colormap. 对于任何高于某个临界值的距离,颜色将从标准颜色图中获取。
  • For any distance lower than some critical value, the colors will linearly go from white to the first color of the previously mentioned map. 对于任何低于某个临界值的距离,颜色将从白色线性变为前面提到的贴图的第一种颜色。

The choices depend fully on what you want to show. 选择完全取决于您要显示的内容。 The colormaps and their sizes depend on your problem. 颜色图及其大小取决于您的问题。 For example, you can choose different types of interpolation: linear, exponential, ...; 例如,您可以选择不同类型的插值:线性,指数,...;。 single- or multi-color colormaps; 单色或多色颜色图; etc.. 等等..

The code: 编码:

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()

The result: 结果:

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM