Plot only on continent in matplotlib

前端 未结 5 766
清歌不尽
清歌不尽 2020-11-27 07:13

I am drawing a map using basemap from matplotlib. The data are spreaded all over the world, but I just want to retain all the data on the continent and drop those on the oce

5条回答
  •  余生分开走
    2020-11-27 07:54

    I was answering this question, when I was told that it would be better to post my answer over here. Basically, my solution extracts the polygons that are used to draw the coastlines of the Basemap instance and combines these polygons with the outline of the map to produce a matplotlib.PathPatch that overlays the ocean areas of the map.

    This especially useful if the data is coarse and interpolation of the data is not wanted. In this case using maskoceans produces a very grainy outline of the coastlines, which does not look very good.

    Here is the same example I posted as answer for the other question:

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

    This produces the following plot:

    Hope this is helpful to someone :)

提交回复
热议问题