1

I'm working on learning my way around using geospatial data in the base Python mapping libraries, and this is my first time working with Shapely/Polygons/Basemap/etc.

I have a set of polygons that describe the neighborhoods in a given area. If I just want to draw them plainly, the below function does the trick (mymap is just a Basemap object, hood_map is a collection of neighborhoods and their associated polygons):

def drawNeighborhoods(mymap,hood_map):
    for hood in hood_map.neighborhoods:
        lon,lat = hood.polygon.exterior.coords.xy
        x,y = mymap(lon,lat)
        mymap.plot(x,y,'-k',color='lightgrey')

This works well and I get the outline of each neighborhood on the map. However, I now want to shade the neighborhoods based on external data I have for each neighborhood (e.g. white if there are no pizzerias, red if there are 100+ pizzerias, etc). To do this, I create a colormap, colorbar, etc like so.

cmap = cm.get_cmap('Reds')
norm = Normalize(vmin=0, vmax=max(number_of_pizza_joints))
cb = ColorbarBase(ax, cmap=cmap, norm=norm)

Then I do this (based off this example https://gist.github.com/urschrei/6436526):

def drawNeighborhoods(mymap,hood_map):
    patches = []
    for hood in hood_map.neighborhoods:
        color = cmap(norm(hood.number_of_pizza_joints))
        lon,lat = hood.polygon.exterior.coords.xy
        x,y = mymap(lon,lat)
        poly = Polygon(zip(x,y))
        patches.append(PolygonPatch(poly,fc=color, ec='#555555', alpha=0.5, zorder=4))
    ax.add_collection(PatchCollection(patches, match_original=True))

Here, I get an error which is:

Traceback (most recent call last):
  File "colorHoodsByPizza.py", line 103, in <module>
    drawNeighborhoods(mymap,hood_map)
  File "colorHoodsByPizza.py", line 52, in drawNeighborhoods
    patches.append(PolygonPatch(poly,fc='#cc00cc', ec='#555555', alpha=0.5, zorder=4))
  File "/Users/zach/anaconda2/lib/python2.7/site-packages/descartes/patch.py", line 87, in PolygonPatch
    return PathPatch(PolygonPath(polygon), **kwargs)
  File "/Users/zach/anaconda2/lib/python2.7/site-packages/descartes/patch.py", line 53, in PolygonPath
    ptype = polygon["type"]
TypeError: 'Polygon' object has no attribute '__getitem__'

My guess is that the getitem error is likely because polygon["type"] doesn't exist, and it should be polygon.type; however this is in a pre-made library 'descartes' so I'm confused as to why this error is coming up. I've tried searching around for this error occurring in descartes, but cannot find any leads; so I assume I'm doing something stupid. Any insights?

Zach
  • 341
  • 1
  • 3
  • 14
  • In the documentation of descrates there is a different call for this function: `# Turn the GeoJSON-ish dict form of the polygon from #1 into a patch geo = polygon.__geo_interface__ patch = PolygonPatch(geo, facecolor='#cccccc', edgecolor='#999999') ax.add_patch(patch)` – Piotr Kamoda Feb 22 '17 at 15:02
  • Just check his examples. The calls are a bit different. I don't know if author expects input given – Piotr Kamoda Feb 22 '17 at 15:06
  • Hi @PiotrKamoda, Thanks for the input. This is true for GeoJSON objects, but for shapely/matplotlib polygons the call should be sufficient without this conversion. See the examples here: https://bitbucket.org/sgillies/descartes/src/4333a49e7339eeeb277c8fa7346b175597a8951c/examples/patches.py?at=default&fileviewer=file-view-default – Zach Feb 22 '17 at 15:24

1 Answers1

1

For the record, I solved this problem after much trial-and-error. It turns out that the import order matters. In this case, I was importing Shapely via another import (import A; inside A.py is import shapely). Descartes was not, for whatever reason, able to interact with the import from the import. So by putting import shapely explicitly in my chain before any other imports of shapely, it works.

Zach
  • 341
  • 1
  • 3
  • 14