In [1]:
from IPython.core.display import HTML

name = '2013-08-12-Brazil_map'

html = """
<small>
<p> This post was written as an IPython notebook.  It is available for
<a href="https://ocefpaf.github.com/python4oceanographers/downloads/
notebooks/%s.ipynb">download</a> or as a static
<a href="https://nbviewer.ipython.org/url/ocefpaf.github.com/
python4oceanographers/downloads/notebooks/%s.ipynb">html</a>.</p>
<p></p>""" % (name, name)

%matplotlib inline
from matplotlib import style
style.use('ggplot')

Creating a map of Brazil with correct states boundaries with basemap.

[basemap](http://matplotlib.org/basemap/) is an excellent tool, but its database lacks up-to-date information regarding the modern states boundaries in Brazil. This post is to show how to overcome that with an custom `shapefile`.

The political boundaries data shipped with basemap is OK for North America and Europe, but it is outdated by several years for South America. In order to draw a more accurate map we need to use custom data from more up-to-date sources.

One source of data are the shapefiles from the "GADM database of Global Administrative Areas". With that data and matplotlib's Polygon we can crate a similar drawstates function to override basemap's defaults.


In [2]:
%matplotlib inline
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon
from mpl_toolkits.basemap import Basemap


def make_map():
    fig, ax = plt.subplots()
    m = Basemap(projection='merc', llcrnrlat=-35, urcrnrlat=7,
                llcrnrlon=-77, urcrnrlon=-32, resolution='i')
    m.ax = ax
    m.fillcontinents()
    return fig, m

Now let's define a new drawstates that makes use of the updated dataset we downloaded:


In [3]:
def drawstates(ax, shapefile='/home/filipe/00-NOBKP/OcFisData/brazil/brazil'):
        shp = m.readshapefile(shapefile, 'states', drawbounds=True)
        for nshape, seg in enumerate(m.states):
            poly = Polygon(seg, facecolor='0.75', edgecolor='k')
            ax.add_patch(poly)

Finally, let's plot the original basemap method to draw states:


In [4]:
fig, m = make_map()
m.drawcountries()
_ = m.drawstates()


And our custom shapefile:


In [5]:
fig, m = make_map()
drawstates(m.ax)


---------------------------------------------------------------------------
OSError                                   Traceback (most recent call last)
<ipython-input-5-5feb917383d9> in <module>()
      1 fig, m = make_map()
----> 2 drawstates(m.ax)

<ipython-input-3-9a92070a5756> in drawstates(ax, shapefile)
      1 def drawstates(ax, shapefile='/home/filipe/00-NOBKP/OcFisData/brazil/brazil'):
----> 2         shp = m.readshapefile(shapefile, 'states', drawbounds=True)
      3         for nshape, seg in enumerate(m.states):
      4             poly = Polygon(seg, facecolor='0.75', edgecolor='k')
      5             ax.add_patch(poly)

/home/luciano/opt/anaconda3/lib/python3.5/site-packages/mpl_toolkits/basemap/__init__.py in readshapefile(self, shapefile, name, drawbounds, zorder, linewidth, color, antialiased, ax, default_encoding)
   2122         shp.default_encoding = default_encoding
   2123         if not os.path.exists('%s.shp'%shapefile):
-> 2124             raise IOError('cannot locate %s.shp'%shapefile)
   2125         if not os.path.exists('%s.shx'%shapefile):
   2126             raise IOError('cannot locate %s.shx'%shapefile)

OSError: cannot locate /home/filipe/00-NOBKP/OcFisData/brazil/brazil.shp

See the difference?


In [ ]:
HTML(html)