Search code examples
pythonmatplotlibshapelydescartes

IndexError - Descartes PolygonPatch wtih shapely


I used to use shapely to make a cirle and plot it on a previously populated plot. This used to work perfectly fine. Recently, I am getting an index error. I broke my code to even the simplest of operations and it cant even do the simplest of circles.

import descartes
import shapely.geometry as sg
import matplotlib.pyplot as plt

circle = sg.Point((0,0)).buffer(1)

# Plot the cricle
fig = plt.figure()
ax = fig.add_subplot(111)
patch = descartes.PolygonPatch(circle)
ax.add_patch(patch)
plt.show()

Below is the error I am getting now. I feel it might be a new version mismatch of something that could have happened. I tried uninstalling and re-installing the last known stable version and that didnt help either

---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
Cell In[20], line 6
      4 fig = plt.figure()
      5 ax = fig.add_subplot(111)
----> 6 patch = descartes.PolygonPatch(circle)
      7 ax.add_patch(patch)
      8 plt.show()

File ~/env/lib/python3.8/site-packages/descartes/patch.py:87, in PolygonPatch(polygon, **kwargs)
     73 def PolygonPatch(polygon, **kwargs):
     74     """Constructs a matplotlib patch from a geometric object
     75 
     76     The `polygon` may be a Shapely or GeoJSON-like object with or without holes.
   (...)
     85 
     86     """
---> 87     return PathPatch(PolygonPath(polygon), **kwargs)

File ~/env/lib/python3.8/site-packages/descartes/patch.py:62, in PolygonPath(polygon)
     58     else:
     59         raise ValueError(
     60             "A polygon or multi-polygon representation is required")
---> 62 vertices = concatenate([
     63     concatenate([asarray(t.exterior)[:, :2]] +
     64                 [asarray(r)[:, :2] for r in t.interiors])
     65     for t in polygon])
     66 codes = concatenate([
     67     concatenate([coding(t.exterior)] +
     68                 [coding(r) for r in t.interiors]) for t in polygon])
     70 return Path(vertices, codes)

File ~/env/lib/python3.8/site-packages/descartes/patch.py:63, in <listcomp>(.0)
     58     else:
     59         raise ValueError(
     60             "A polygon or multi-polygon representation is required")
     62 vertices = concatenate([
---> 63     concatenate([asarray(t.exterior)[:, :2]] +
     64                 [asarray(r)[:, :2] for r in t.interiors])
     65     for t in polygon])
     66 codes = concatenate([
     67     concatenate([coding(t.exterior)] +
     68                 [coding(r) for r in t.interiors]) for t in polygon])
     70 return Path(vertices, codes)

IndexError: too many indices for array: array is 0-dimensional, but 2 were indexed

Solution

  • So from what I could tell, this issue comes from a broken implementation of shapely within descartes.

    My speculation is that shapely changed how it handles Polygon exteriors and descartes simply hasn't been updated.

    I don't know if it is the best idea, but I edited my installation of descartes directly to fix this issue:

    1. Navigate to your descartes installation and open patch.py.

    2. At line 62 you should see this piece of code:

       vertices = concatenate([
       concatenate([asarray(t.exterior)[:, :2]] + [asarray(r)[:, :2] for r in t.interiors])
       for t in polygon])
      

    Simply change t.exterior to t.exterior.coords. This hopefully should fix your issue.

        vertices = concatenate([
        concatenate([asarray(t.exterior.coords)[:, :2]] + [asarray(r)[:, :2] for r in t.interiors])
        for t in polygon])
    

    I'm trying to find a way to provide the descartes devs with this feedback.