[英]Mask Ocean or Land from data using Cartopy
我想從全球海面溫度數據中掩蓋陸地區域。 我正在使用 Cartopy 來 plot 數據。
import numpy as np
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
from netCDF4 import Dataset
f = Dataset('sst.mnmean.nc')
sst = f.variables['sst'][0,:,:]
lats = f.variables['lat'][:]
lons = f.variables['lon'][:]
ax = plt.axes(projection=ccrs.PlateCarree())
ax.coastlines()
plot = ax.contourf(lons, lats, sst, 60, transform=ccrs.PlateCarree())
cb = plt.colorbar(plot)
plt.show()
我想以此掩蓋土地。
我瀏覽了cartopy文檔,並遇到了名為add_feature的方法。 代碼如下:
import numpy as np
import matplotlib.pyplot as plt
import cartopy as cart
from mpl_toolkits.basemap import Basemap
from netCDF4 import Dataset
f = Dataset('sst.mnmean.nc')
sst = f.variables['sst'][0,:,:]
lats = f.variables['lat'][:]
lons = f.variables['lon'][:]
ax = plt.axes(projection=cart.crs.PlateCarree())
ax.coastlines()
ax.add_feature(cart.feature.LAND, zorder=100, edgecolor='k')
ax.set_global()
plot = ax.contourf(lons, lats, sst, 60, transform=cart.crs.PlateCarree())
cb = plt.colorbar(plot)
plt.show()
現在情節看起來像這樣 。 要遮蓋海洋, cart.feature.LAND
cart.feature.OCEAN
更改為cart.feature.OCEAN
為了掩蓋陸地區域,使用底圖會更容易。
from mpl_toolkits.basemap import Basemap
map = Basemap(projection='mill',lon_0=180) # create projection
.... # whatever processing needed
map.fillcontinents(color='coral') # mask land mass
公認的解決方案並沒有真正掩蓋數據,plot 只是通過覆蓋 map 部分覆蓋。 雖然這很好地解決了給定的問題,但有時需要一個實際的掩碼來刪除數據中不需要的部分。 可以基於用於陸地或海洋的光柵化 map輕松創建這樣的蒙版。
使用下面的代碼,創建了一個臨時圖形,其分辨率對應於給定的數據。 繪制土地 map 后,使用tostring_rgb()
獲得 map 的光柵化圖像。 該圖像類似於二值圖像,然后可以直接用於為數據創建掩碼。
這種解決方案的優點是它可以應用於更一般的問題,例如分別在陸地和海洋上繪制兩個不同的數據集。 在繪制類似圖像的數據時,好處會有所提高,因為通過考慮光柵化蒙版的顏色梯度,可以使用透明度來實現平滑的邊緣。 這可以通過PIL.Image.fromarray(mask)
然后convert('L')
並最后在給定圖像上應用putalpha(mask)
輕松完成。
import matplotlib.pyplot as plt
import numpy as np
import cartopy
import netCDF4
# load data
data = netCDF4.Dataset('sst.mnmean.nc')
sst = data.variables['sst'][0,:,:]
lats = data.variables['lat'][:]
lons = data.variables['lon'][:]
# prepare temporary plot and create mask from rasterized map
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)
# create actual plot
fig, ax = plt.subplots(subplot_kw=proj)
ax.contourf(lons, lats, sst, 60, transform=cartopy.crs.PlateCarree(central_longitude=180))
ax.coastlines()
plt.show()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.