world map without rivers with matplotlib / Basemap?

后端 未结 7 691
生来不讨喜
生来不讨喜 2021-01-31 10:37

Would there be a way to plot the borders of the continents with Basemap (or without Basemap, if there is some other way), without those annoying rivers coming along? Especially

7条回答
  •  爱一瞬间的悲伤
    2021-01-31 11:11

    If you're OK with plotting outlines rather than shapefiles, it's pretty easy to plot coastlines that you can get from wherever. I got my coastlines from the NOAA Coastline Extractor in MATLAB format: http://www.ngdc.noaa.gov/mgg/shorelines/shorelines.html

    To edit the coastlines, I converted to SVG, then edited them with Inkscape, then converted back to the lat/lon text file ("MATLAB" format).

    All Python code is included below.

    # ---------------------------------------------------------------
    def plot_lines(mymap, lons, lats, **kwargs) :
        """Plots a custom coastline.  This plots simple lines, not
        ArcInfo-style SHAPE files.
    
        Args:
            lons: Longitude coordinates for line segments (degrees E)
            lats: Latitude coordinates for line segments (degrees N)
    
        Type Info:
            len(lons) == len(lats)
            A NaN in lons and lats signifies a new line segment.
    
        See:
            giss.noaa.drawcoastline_file()
        """
    
        # Project onto the map
        x, y = mymap(lons, lats)
    
        # BUG workaround: Basemap projects our NaN's to 1e30.
        x[x==1e30] = np.nan
        y[y==1e30] = np.nan
    
        # Plot projected line segments.
        mymap.plot(x, y, **kwargs)
    
    
    # Read "Matlab" format files from NOAA Coastline Extractor.
    # See: http://www.ngdc.noaa.gov/mgg/coast/
    
    lineRE=re.compile('(.*?)\s+(.*)')
    def read_coastline(fname, take_every=1) :
        nlines = 0
        xdata = array.array('d')
        ydata = array.array('d')
        for line in file(fname) :
    #        if (nlines % 10000 == 0) :
    #            print 'nlines = %d' % (nlines,)
            if (nlines % take_every == 0 or line[0:3] == 'nan') :
                match = lineRE.match(line)
                lon = float(match.group(1))
                lat = float(match.group(2))
    
                xdata.append(lon)
                ydata.append(lat)
            nlines = nlines + 1
    
    
        return (np.array(xdata),np.array(ydata))
    
    def drawcoastline_file(mymap, fname, **kwargs) :
        """Reads and plots a coastline file.
        See:
            giss.basemap.drawcoastline()
            giss.basemap.read_coastline()
        """
    
        lons, lats = read_coastline(fname, take_every=1)
        return drawcoastline(mymap, lons, lats, **kwargs)
    # =========================================================
    # coastline2svg.py
    #
    import giss.io.noaa
    import os
    import numpy as np
    import sys
    
    svg_header = """
    
    
    
      
      
        
          
            image/svg+xml
            
            
          
        
      
      
    """
    
    path_tpl = """
         2 :
                out.write('\n\n')
                path_id += 1
            points = []
        else :
            lon += 180
            lat = 180 - (lat + 90)
            points.append((lon, lat))
    
    
    out.write(svg_footer)
    out.close()
    
    # =============================================================
    # svg2coastline.py
    
    import os
    import sys
    import re
    
    # Reads the output of Inkscape's "Plain SVG" format, outputs in NOAA MATLAB coastline format
    
    mainRE = re.compile(r'\s*d=".*"')
    lineRE = re.compile(r'\s*d="(m|M)\s*(.*?)"')
    
    fname = sys.argv[1]
    
    
    lons = []
    lats = []
    for line in open(fname, 'r') :
        # Weed out extraneous lines in the SVG file
        match = mainRE.match(line)
        if match is None :
            continue
    
        match = lineRE.match(line)
    
        # Stop if something is wrong
        if match is None :
            sys.stderr.write(line)
            sys.exit(-1)
    
        type = match.group(1)[0]
        spairs = match.group(2).split(' ')
        x = 0
        y = 0
        for spair in spairs :
            if spair == 'L' :
                type = 'M'
                continue
    
            (sdelx, sdely) = spair.split(',')
            delx = float(sdelx)
            dely = float(sdely)
            if type == 'm' :
                x += delx
                y += dely
            else :
                x = delx
                y = dely
            lon = x - 180
            lat = 90 - y
            print '%f\t%f' % (lon, lat)
        print 'nan\tnan'
    

提交回复
热议问题