所接受的解决方案实际上并没有掩盖数据,而是通过覆盖地图的部分来遮盖绘图。虽然这对于给定的问题很好用,但有时需要一个真正的掩码来去除数据中不需要的部分。这样的掩码可以基于陆地或海洋的光栅地图轻松创建。
使用下面的代码,创建一个临时图形,其分辨率与给定数据相对应。在绘制陆地地图之后,使用
tostring_rgb()
获取地图的<
rasterized image>。该图像类似于二进制图像,然后可以直接用于创建数据的掩码。
这种解决方案的优点在于它可以应用于更一般的问题,例如在陆地和海洋上分别绘制两个不同的数据集。当绘制像图像一样的数据时,由于可以考虑光栅化掩码的颜色梯度,因此可以使用透明度实现平滑的边缘。这可以通过
PIL.Image.fromarray(mask)
,然后跟随
convert('L')
和最后在给定图像上应用
putalpha(mask)
轻松完成。
import matplotlib.pyplot as plt
import numpy as np
import cartopy
import netCDF4
data = netCDF4.Dataset('sst.mnmean.nc')
sst = data.variables['sst'][0,:,:]
lats = data.variables['lat'][:]
lons = data.variables['lon'][:]
proj = {'projection': cartopy.crs.PlateCarree()}
fig, ax = plt.subplots(figsize=(len(lons)/100, len(lats)/100), dpi=100, subplot_kw=proj)
fig.subplots_adjust(left=0.0, bottom=0.0, right=1.0, top=1.0)
ax.set_frame_on(False)
ax.add_feature(cartopy.feature.LAND, facecolor='black')
fig.canvas.draw()
mask = fig.canvas.tostring_rgb()
ncols, nrows = fig.canvas.get_width_height()
plt.close(fig)
mask = np.frombuffer(mask, dtype=np.uint8).reshape(nrows, ncols, 3)
mask = mask.mean(axis=2)
sst = np.where(mask>0, sst, np.nan)
fig, ax = plt.subplots(subplot_kw=proj)
ax.contourf(lons, lats, sst, 60, transform=cartopy.crs.PlateCarree(central_longitude=180))
ax.coastlines()
plt.show()
![Resulting plot](https://istack.dev59.com/BtIxr.webp)