在底图中填充海洋

时间:2018-02-05 10:46:28

标签: python matplotlib mask matplotlib-basemap

我试图在mongodump上绘制1x1度数据,我想用白色填充海洋。但是,为了使海洋边界遵循matplotlib.Basemap绘制的海岸线,白海洋掩模的分辨率应远高于我的数据分辨率。

在搜索了很长时间后,我尝试了两种可能的解决方案:

(1)matplotlibmaskoceans()函数,但由于我的数据分辨率低于底图绘制的地图,因此边缘看起来不太好。我不想将我的数据插入到更高的分辨率。

(2)is_land(),但由于无法分配zorder,因此pcolormesh图总是覆盖蒙版。

此代码

m.drawlsmask()

制作此图片: result of the above code

添加import numpy as np import matplotlib.pyplot as plt import mpl_toolkits.basemap as bm #Make data lon = np.arange(0,360,1) lat = np.arange(-90,91,1) data = np.random.rand(len(lat),len(lon)) #Draw map plt.figure() m = bm.Basemap(resolution='i',projection='laea', width=1500000, height=2900000, lat_ts=60, lat_0=72, lon_0=319) m.drawcoastlines(linewidth=1, color='white') data, lon = bm.addcyclic(data,lon) x,y = m(*np.meshgrid(lon,lat)) plt.pcolormesh(x,y,data) plt.savefig('1.png',dpi=300) 会生成以下图像,这是我需要的,但要填充海洋而不是土地。 same as above, but with countries drawn on top

修改

m.fillcontinents(color='white')也填补了土地,因此无法使用。

期望的结果是海洋是白色的,而我用m.drawmapboundary(fill_color='lightblue')绘制的东西显示在陆地上。

1 个答案:

答案 0 :(得分:2)

我发现了一个更好的解决方案,它使用地图中海岸线定义的多边形来生成覆盖海洋区域的nvcc。这个解决方案具有更好的分辨率,速度更快:

matplotlib.PathPatch

输出如下:

result of the above code

原始解决方案

您可以在from matplotlib import pyplot as plt from mpl_toolkits import basemap as bm from matplotlib import colors import numpy as np import numpy.ma as ma from matplotlib.patches import Path, PathPatch fig, ax = plt.subplots() lon_0 = 319 lat_0 = 72 ##some fake data lons = np.linspace(lon_0-60,lon_0+60,10) lats = np.linspace(lat_0-15,lat_0+15,5) lon, lat = np.meshgrid(lons,lats) TOPO = np.sin(np.pi*lon/180)*np.exp(lat/90) m = bm.Basemap(resolution='i',projection='laea', width=1500000, height=2900000, lat_ts=60, lat_0=lat_0, lon_0=lon_0, ax = ax) m.drawcoastlines(linewidth=0.5) x,y = m(lon,lat) pcol = ax.pcolormesh(x,y,TOPO) ##getting the limits of the map: x0,x1 = ax.get_xlim() y0,y1 = ax.get_ylim() map_edges = np.array([[x0,y0],[x1,y0],[x1,y1],[x0,y1]]) ##getting all polygons used to draw the coastlines of the map polys = [p.boundary for p in m.landpolygons] ##combining with map edges polys = [map_edges]+polys[:] ##creating a PathPatch codes = [ [Path.MOVETO] + [Path.LINETO for p in p[1:]] for p in polys ] polys_lin = [v for p in polys for v in p] codes_lin = [c for cs in codes for c in cs] path = Path(polys_lin, codes_lin) patch = PathPatch(path,facecolor='white', lw=0) ##masking the data: ax.add_patch(patch) plt.show() 中使用分辨率更高的数组,以使分辨率符合大陆轮廓。然后,您可以反转蒙版并在数据上绘制蒙版数组。

不知怎的,当我使用地图的全部范围时(例如从-180到180的经度和从-90到90的纬度),我只有basemap.maskoceans才能工作。鉴于需要相当高的分辨率使其看起来不错,计算需要一段时间:

basemap.maskoceans

结果如下:

result of above code