Working with shapefiles¶

The way used by Basemap to handle vectorial files is quite different from other libraries, and deserves some attending.

Basic usage¶

Let'southward start with the easiest way to plot a shapefile:

                                from                mpl_toolkits.basemap                import                Basemap                import                matplotlib.pyplot                as                plt                map                =                Basemap                (                llcrnrlon                =-                0.5                ,                llcrnrlat                =                39.viii                ,                urcrnrlon                =                4.                ,                urcrnrlat                =                43.                ,                resolution                =                'i'                ,                projection                =                'tmerc'                ,                lat_0                =                39.five                ,                lon_0                =                1                )                map                .                drawmapboundary                (                fill_color                =                'aqua'                )                map                .                fillcontinents                (                color                =                '#ddaa66'                ,                lake_color                =                'aqua'                )                map                .                drawcoastlines                ()                                  map                  .                  readshapefile                  (                  '../sample_files/comarques'                  ,                  'comarques'                  )                                plt                .                testify                ()              

_images/readshapefile_polygon.png

  • The first parameter shapefile name must get without the shp extension. The library assumes that all shp, sbf and shx files will exist with this given proper noun
  • The 2nd parameter is a name to admission later on to the shapefile information from the Basemap instance, as we will show after

There are some restrictions:

  • The file must be in EPSG:4326, or lat/lon coordinates. If your file isn't, you can use ogr2ogr to transform information technology
  • The elements must have simply 2 dimensions
  • This example will show something just if the elements are polygons or polylines

As the image shows, the result volition exist only the boundary of the polygons (or the polylines). To fill up them, wait at the last section Filling polygons

Reading point data¶

Plotting points is a bit more complicated. First, the shapefile is read, and then the points can be plotted using scatter, plot or the matplotlib office that fits better the needs.

                                from                mpl_toolkits.basemap                import                Basemap                import                matplotlib.pyplot                as                plt                map                =                Basemap                (                llcrnrlon                =-                0.5                ,                llcrnrlat                =                39.viii                ,                urcrnrlon                =                4.                ,                urcrnrlat                =                43.                ,                resolution                =                'i'                ,                projection                =                'tmerc'                ,                lat_0                =                39.v                ,                lon_0                =                1                )                map                .                drawmapboundary                (                fill_color                =                'aqua'                )                map                .                fillcontinents                (                color                =                '#ddaa66'                ,                lake_color                =                'aqua'                )                map                .                drawcoastlines                ()                map                .                readshapefile                (                '../sample_files/comarques'                ,                'comarques'                )                                  lightning_info                  =                  map                  .                  readshapefile                  (                  '../sample_files/lightnings'                  ,                  'lightnings'                  )                                                                                  print                  lightning_info                                                                                  for                  info                  ,                  lightning                  in                  nada                  (                  map                  .                  lightnings_info                  ,                  map                  .                  lightnings                  ):                                                  if                  float                  (                  info                  [                  'aamplitude'                  ])                  <                  0                  :                                                  marker                  =                  '_'                                                  else                  :                                                  marker                  =                  '+'                                                  map                  .                  plot                  (                  lightning                  [                  0                  ],                  lightning                  [                  ane                  ],                  marker                  =                  marker                  ,                  color                  =                  'one thousand'                  ,                  markersize                  =                  8                  ,                  markeredgewidth                  =                  2                  )                                plt                .                show                ()              

The example shows the lightnings fallen over Catalonia during a storm

_images/readshapefile_points.png

  • The 2nd parameter has been named lightnings, and the Basemap instance map, so the shapefile elements tin can be accessed using map.lightnings for geometries and map.lightnings_info for accessing the elements fields
  • The shapefile method returns a sequence with the number of elements, the geometry type with the codes defined here and the bounding box
  • Line 17 shows a possible way to iterate all the elements
    • nix will join each geometry with its field values
    • each chemical element can be iterated with a for every bit when iterating a dict
  • In the example, a field named amplitude can exist used to guess if the lightning had positive or negative current and draw a different symbol for each case
  • The points are plotted with the method plot, using the marker attribute to alter the symbol

Polygon data¶

This example shows how to use the shapefile attributes to select but some geometries.

                                from                mpl_toolkits.basemap                import                Basemap                import                matplotlib.pyplot                as                plt                map                =                Basemap                (                llcrnrlon                =-                0.5                ,                llcrnrlat                =                39.8                ,                urcrnrlon                =                4.                ,                urcrnrlat                =                43.                ,                resolution                =                'i'                ,                projection                =                'tmerc'                ,                lat_0                =                39.5                ,                lon_0                =                1                )                map                .                drawmapboundary                (                fill_color                =                'aqua'                )                map                .                fillcontinents                (                color                =                '#ddaa66'                ,                lake_color                =                'aqua'                )                map                .                drawcoastlines                ()                map                .                readshapefile                (                '../sample_files/comarques'                ,                'comarques'                ,                drawbounds                =                False                )                                  for                  info                  ,                  shape                  in                  zip                  (                  map                  .                  comarques_info                  ,                  map                  .                  comarques                  ):                                                  if                  info                  [                  'nombre'                  ]                  ==                  'Selva'                  :                                                  x                  ,                  y                  =                  nada                  (                  *                  shape                  )                                                  map                  .                  plot                  (                  10                  ,                  y                  ,                  marker                  =                  None                  ,                  color                  =                  'm'                  )                                plt                .                show                ()              

_images/readshapefile_polygon_info.png

  • To iterate all the elements, use zip equally in the last example
  • There is a field called 'nombre' that tin be used to filter. In the instance only the value 'Selva' is selected
  • To plot a line, the 10 and y coordinates must exist in separated arrays, only the geometry gives each betoken as a pair. In that location is an explanation on how to do it 'here <http://stackoverflow.com/questions/13635032/what-is-the-inverse-role-of-zip-in-python>'_
  • The shape is plotted using the plot method, eliminating the markers to get only a line

Filling polygons¶

The basic way to plot a shapefile doesn't fill up the polygons if this is the shape blazon. Here's how to exercise it:

                                from                mpl_toolkits.basemap                import                Basemap                import                matplotlib.pyplot                as                plt                from                matplotlib.patches                import                Polygon                from                matplotlib.collections                import                PatchCollection                from                matplotlib.patches                import                PathPatch                import                numpy                as                np                fig                =                plt                .                figure                ()                ax                =                fig                .                add_subplot                (                111                )                map                =                Basemap                (                llcrnrlon                =-                0.5                ,                llcrnrlat                =                39.8                ,                urcrnrlon                =                4.                ,                urcrnrlat                =                43.                ,                resolution                =                'i'                ,                projection                =                'tmerc'                ,                lat_0                =                39.5                ,                lon_0                =                ane                )                map                .                drawmapboundary                (                fill_color                =                'aqua'                )                map                .                fillcontinents                (                color                =                '#ddaa66'                ,                lake_color                =                'aqua'                )                map                .                drawcoastlines                ()                map                .                readshapefile                (                '../sample_files/comarques'                ,                'comarques'                ,                drawbounds                =                Fake                )                                  patches                  =                  []                                                                                  for                  info                  ,                  shape                  in                  zip                  (                  map                  .                  comarques_info                  ,                  map                  .                  comarques                  ):                                                  if                  info                  [                  'nombre'                  ]                  ==                  'Selva'                  :                                                  patches                  .                  append                  (                  Polygon                  (                  np                  .                  array                  (                  shape                  ),                  True                  )                  )                                                                                  ax                  .                  add_collection                  (                  PatchCollection                  (                  patches                  ,                  facecolor                  =                  'm'                  ,                  edgecolor                  =                  'k'                  ,                  linewidths                  =                  i.                  ,                  zorder                  =                  ii                  ))                                plt                .                show                ()              

_images/readshapefile_polygon_fill.png

  • matplotlib uses a class called PatchCollection, which is a set up shaped to add filled polygons, every bit explained at the official docs.
  • The shapes, in this case, are of the blazon Polygon. To create it, the coordinates must be in a numpy array. The 2nd statement sets the polygon to be closed

I learned it how to do it at StackOverflow