IndexError - Descartes PolygonPatch wtih shapely
Asked Answered
M

3

5

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
Mitchum answered 30/1, 2023 at 16:46 Comment(0)
U
20

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.

Undernourished answered 9/2, 2023 at 23:35 Comment(2)
I have NO IDEA how you found this but this solved it perfectly. Thanks!Mitchum
The problem seems to remain 10/2024 with descartes==1.1.0 and ubuntu 24.04Malversation
K
2

I was testing the answer that Jacob gave but was getting a similar error on the next line for t.interiors . I tried a similar fix to what he suggested for the exteriors, changing line 64 to [asarray(r.coords)[:, :2] for r in t.interiors] but it did not fully work (another error just propagated through the package).

In the end I had to downgrade Shapely to 1.7 so descartes could work again. So my suggestion is to work with older versions of it while the package of descartes is not upgraded for newer versions of Shapely.

Koser answered 7/6, 2023 at 11:45 Comment(1)
the issue is with the internal shapely of descrates. I am using descrates 1.1.0 and shapely 2.0.1 and that fix has worked for me on mulitple machinesMitchum
A
2

I believe the correct fix is:

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

This works with descartes 1.1.0 and shapely 2.0.1

Abagael answered 17/1 at 10:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.