Fill countries in python basemap

basemap python
python basemap city
matplotlib basemap axes
python geographic maps
choropleth map python
basemap python north america
python basemap draw rivers
basemap projections

Hi I am trying to plot a map using pythons basemap with some countries filled in a certain colour.

Is there a quick and easy solution out there??

As has already been said by @unutbu, Thomas' post here is exactly what you are after.

Should you want to do this with Cartopy, the corresponding code (in v0.7) can be adapted from http://scitools.org.uk/cartopy/docs/latest/tutorials/using_the_shapereader.html slightly:

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

Drawing a Map Background, Matplotlib always tries to fill the inside of a polygon. draw country boundaries. drawstates() : draw state boundaries in North America. drawrivers() : draw rivers. Fill countries in python basemap. Ask Question Asked 7 years, 5 months ago. fill in each zip-code with a different color for basemap of Matplotlib in Python 3.2. 1.

Inspired by the answer from pelson, I post the solution I have. I will leave it up to you which works best, so I will not accept any answer at the moment.

#! /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)

This is the result

Here is my example how to fill in Albania in the correct colour (not very elegant I know ;)).

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

It is important that you do this after you have done all the other shapes. Perhaps you can get rid of some part of this code, but as I said it was sufficient for me.

For my application I coloured contries by name or continent, therefore these lines:

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

The data used I got from this website: http://www.naturalearthdata.com/

Creating a Choropleth Map of the World in Python using Basemap , set_index('Country Code', inplace=True) df = df.ix[iso3_codes].dropna() # Filter out non-countries and missing values. To map data values to  Fill countries in python basemap. Ask Question Asked 7 years, 2 months ago. Active 1 year, 7 months ago. Viewed 23k times 18. 13. Hi I am trying to plot a map using

Updating @pelson answer for 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()

#286 Boundaries provided in Basemap – The Python Graph Gallery, Countries; Counties; States. #286 Country boundaries. To show the countries on your map, use the map.drawcountries function  I am trying to plot 1x1 degree data on a matplotlib.Basemap, and I want to fill the ocean with white.However, in order for the boundaries of the ocean to follow the coastlines drawn by matplotlib, the resolution of the white ocean mask should be much higher than the resolution of my data.

Geographic Data with Basemap, Matplotlib's main tool for this type of visualization is the Basemap toolkit, which is rivers, as well as political boundaries such as countries and US states and counties. drawmapboundary() : Draw the map boundary, including the fill color for  I would like to plot a trajectory on a Basemap, and have country labels (names) shown as an overlay. Here is the current code and the map it produces: import pandas as pd import matplotlib.pyplo

Drawing the first map, from mpl_toolkits.basemap import Basemap import matplotlib.pyplot as plt map Even with the new projection, the map is still a bit poor, so let's fill the oceans  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 that piece of Kongo

Basemap in 3D, The most important thing to know when starting with 3d matplotlib plots is that the The coast lines and the countries are drawn as in the previous example  Basemap Tutorial This brief tutorial will look at the Basemap toolkit extension for matplotlib. Basemap allows you to create map plots in python. It extends matplotlib's functionality by adding geographical projections and some datasets for plotting coast lines and political boundaries, among other things. We only have time to cover a few examples here, which I have modified from a few places:

Comments
  • Maybe useful: geophysique.be/2011/01/27/…
  • I beleive this helps: matplotlib.1069221.n5.nabble.com/…
  • Thanks for those comments, they where most helpful. I also found a site with free country data, which was just what I was looking for: http://www.naturalearthdata.com/
  • @red_tiger - you could answer your own question with a small code snippet and output?
  • Please note that you should post the essential parts of the answer here, on this site, or your post risks being deleted See the FAQ where it mentions answers that are 'barely more than a link'. You may still include the link if you wish, but only as a 'reference'. The answer should stand on its own without needing the link.
  • Thanks @bluefeet - I can see why that would be the case. I've updated the answer to give some new information (without duplicating the original link, which I did not own the copyright on). Cheers,
  • Calling shpreader.natural_earth gives me an http 404 not found error, it apparently tries to download it?
  • That's right. There are gigabytes of data available to you on Natural Earth - it wouldn't be practical to install them all. If you update your cartopy version to v0.11.2 the recent change in NaturalEarth's URL scheme will be reflected, and you will no longer get a 404. github.com/SciTools/cartopy/pull/472 relates.
  • Yes, actually the same happens to Armenia. I had to to a work arround, by explicitly filling these two countries in afterwards. The inquiery with the people from naturalearthdata was not conclusive and I did not follow this up once I fixed it for me
  • @red_tiger I have the same problem with Argentina and Angola. Can you post your solution to the "Albanian problem"? What did the folks at NaturalEarth say? Thanks.
  • @red_tiger Does Albania appear if you change the alpha? For example lines.set_alpha(0.5)?
  • @tommy.carstensen see my updated answer for your first question. I opened a topic in the NaturalEarth data forum (naturalearthdata.com/forums/topic/armenia-under-water) but it was not conclusive. And I did not follow it up after I got this hack implemented. And for your last question. I have not tried this, but do let me know if that has a positive effect.