填写蟒蛇底图国家(Fill countries in python basemap)

2019-06-21 04:00发布

嗨,我想要绘制使用蟒蛇与一些国家充满某种颜色底图的地图。

是否有一个快速和简单的解决方案在那里?

Answer 1:

正如已经被@unutbu说,托马斯的后这里正是你所追求的。

如果你想与Cartopy,相应的代码(在V0.7)要做到这一点可以从适应http://scitools.org.uk/cartopy/docs/latest/tutorials/using_the_shapereader.html咯:

import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import cartopy.io.shapereader as shpreader
import itertools
import numpy as np

shapename = 'admin_0_countries'
countries_shp = shpreader.natural_earth(resolution='110m',
                                        category='cultural', name=shapename)

# some nice "earthy" colors
earth_colors = np.array([(199, 233, 192),
                                (161, 217, 155),
                                (116, 196, 118),
                                (65, 171, 93),
                                (35, 139, 69),
                                ]) / 255.
earth_colors = itertools.cycle(earth_colors)



ax = plt.axes(projection=ccrs.PlateCarree())
for country in shpreader.Reader(countries_shp).records():
    print country.attributes['name_long'], earth_colors.next()
    ax.add_geometries(country.geometry, ccrs.PlateCarree(),
                      facecolor=earth_colors.next(),
                      label=country.attributes['name_long'])

plt.show()



Answer 2:

从pelson答案的启发,我发布了解决方案,我有。 我将离开你来决定哪个最,所以我不会接受目前的任何答案。

#! /usr/bin/env python

import sys
import os
from pylab import *
from mpl_toolkits.basemap import Basemap
import matplotlib as mp

from shapelib import ShapeFile
import dbflib
from matplotlib.collections import LineCollection
from matplotlib import cm

def get_shapeData(shp,dbf):
  for npoly in range(shp.info()[0]):
    shpsegs = []
    shpinfo = []

    shp_object = shp.read_object(npoly)
    verts = shp_object.vertices()
    rings = len(verts)
    for ring in range(rings):
        if ring == 0:
            shapedict = dbf.read_record(npoly)
        name = shapedict["name_long"]
        continent = shapedict["continent"]
        lons, lats = zip(*verts[ring])
        if max(lons) > 721. or min(lons) < -721. or max(lats) > 91. or min(lats) < -91:
            raise ValueError,msg
        x, y = m(lons, lats)
        shpsegs.append(zip(x,y))
        shapedict['RINGNUM'] = ring+1
        shapedict['SHAPENUM'] = npoly+1
        shpinfo.append(shapedict)

    lines = LineCollection(shpsegs,antialiaseds=(1,))
    lines.set_facecolors(cm.jet(np.random.rand(1)))
    lines.set_edgecolors('k')
    lines.set_linewidth(0.3)
    ax.add_collection(lines)


if __name__=='__main__':

  f=figure(figsize=(10,10))
  ax = plt.subplot(111)
  m = Basemap(projection='merc',llcrnrlat=30,urcrnrlat=72,\
            llcrnrlon=-40,urcrnrlon=50,resolution='c')
  m.drawcountries(linewidth=0.1,color='w')

  sfile = 'ne_10m_admin_0_countries'

  shp = ShapeFile(sfile)
  dbf = dbflib.open(sfile)
  get_shapeData(shp,dbf)

  show()
  sys.exit(0)

这是结果

这是我的例子,如何填补阿尔巴尼亚在正确的颜色(不是很优雅,我知道;))。

  #HACK for Albania
  shpsegs = []
  shpinfo = []

  shp_object = shp.read_object(9)
  verts = shp_object.vertices()
  rings = len(verts)
  for ring in range(rings):
      if ring == 0:
          shapedict = dbf.read_record(9)
      name = shapedict["name_long"]
      continent = shapedict["continent"]
      lons, lats = zip(*verts[ring])
      if max(lons) > 721. or min(lons) < -721. or max(lats) > 91. or min(lats) < -91:
          raise ValueError,msg
      x, y = m(lons, lats)
      shpsegs.append(zip(x,y))
      shapedict['RINGNUM'] = ring+1
      shapedict['SHAPENUM'] = npoly+1
      shpinfo.append(shapedict)
  lines = LineCollection(shpsegs,antialiaseds=(1,))
  if name == 'Albania':
    lines.set_facecolors('w')
  lines.set_edgecolors('k')
  lines.set_linewidth(0.3)
  ax.add_collection(lines)

你这样做,你已完成所有其他形状后,这一点很重要。 也许你可以摆脱这个代码的某些部分,但正如我说,这是够我用。

对于我的应用程序有色通过名称或大陆,因此,这些线路contries:

    name = shapedict["name_long"]
    continent = shapedict["continent"]

所使用的数据,我从这个网站有: http://www.naturalearthdata.com/



Answer 3:

更新@pelson答案为Python 3:

import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import cartopy.io.shapereader as shpreader
import itertools
import numpy as np

shapename = 'admin_0_countries'
countries_shp = shpreader.natural_earth(resolution='110m',
                                        category='cultural', name=shapename)

print(countries_shp)

# some nice "earthy" colors
earth_colors = np.array([(199, 233, 192),
                         (161, 217, 155),
                         (116, 196, 118),
                         (65, 171, 93),
                         (35, 139, 69),
                        ]) / 255
earth_colors = itertools.cycle(earth_colors)

ax = plt.axes(projection=ccrs.PlateCarree())

for country in shpreader.Reader(countries_shp).records():
    print(country.attributes['NAME_LONG'], next(earth_colors))
    ax.add_geometries(country.geometry, ccrs.PlateCarree(),
                      facecolor=next(earth_colors),
                      label=country.attributes['NAME_LONG'])

plt.show()


文章来源: Fill countries in python basemap