在底图中填充海洋[重复]

发布于 2021-01-29 16:35:42

这个问题已经在这里有了答案

仅在matplotlib中的大陆上绘图 (5个答案)

2年前关闭。

我正在尝试在上绘制1x1度数据matplotlib.Basemap,并且我想用白色填充海洋。但是,为了使海洋的边界能够遵循绘制的海岸线matplotlib,白海面具的分辨率应该比我的数据分辨率高得多。

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

(1)maskoceans()is_land()功能,但由于我的数据分辨率低于底图绘制的地图,因此边缘看起来不佳。我也不想将数据插值到更高的分辨率。

(2)m.drawlsmask(),但是由于无法分配zorder,因此pcolormesh图始终覆盖在蒙版上。

这段代码

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)

产生此图像:
以上代码的结果

添加m.fillcontinents(color='white')会产生以下图像,这是我需要的,但要填充海洋而不是土地。
与上述相同,但国家位于首位

编辑

m.drawmapboundary(fill_color='lightblue') 也填满土地,因此无法使用。

理想的结果是海洋是白色的,而我所绘制的图像plt.pcolormesh(x,y,data)显示在陆地上。

关注者
0
被浏览
43
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    我发现了一个更好的解决方案,即使用地图中海岸线定义的多边形来产生matplotlib.PathPatch覆盖海洋区域的多边形。该解决方案具有更好的分辨率,并且速度更快:

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

    输出如下:

    以上代码的结果

    原始解决方案

    您可以在中使用分辨率更高的数组basemap.maskoceans,以使分辨率适合大陆轮廓。然后,您只需反转蒙版并将蒙版数组绘制在数据之上。

    不知何故,我只有basemap.maskoceans在使用整个地图范围时才可以工作(例如,经度从-180到180,纬度从-90到90)。鉴于需要很高的分辨率才能使其看起来不错,因此计算需要一段时间:

    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
    
    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)
    
    
    ##producing a mask -- seems to only work with full coordinate limits
    lons2 = np.linspace(-180,180,10000)
    lats2 = np.linspace(-90,90,5000)
    lon2, lat2 = np.meshgrid(lons2,lats2)
    x2,y2 = m(lon2,lat2)
    pseudo_data = np.ones_like(lon2)
    masked = bm.maskoceans(lon2,lat2,pseudo_data)
    masked.mask = ~masked.mask
    
    ##plotting the mask
    cmap = colors.ListedColormap(['w'])
    pcol = ax.pcolormesh(x2,y2,masked, cmap=cmap)
    
    plt.show()
    

    结果看起来像这样:

    以上代码的结果



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看