Search code examples
pythonmatplotlibgispolygonshapely

Problem with shapely polygon contain, seems not to correctly flag all contained points


Lets say we have a 100x100 grid that contains a polygon. Now if we color all possible (x,y) points [x,y are integers] that are contained in the polygon we should expect the polygon to be somewhat painted/filled

But the image that i'm getting never properly falls within and fills the polygon! Is this a limitation of shapely or am I doing something wrong?! (please note I need this to work for other purposes and not just paiting a polygon)

polygon and filled area not overlapping

import numpy as np
import matplotlib.pyplot as plt
import shapely.geometry

points = np.random.randint(0,100, (10,2)) # 10 random points
poly   = shapely.geometry.MultiPoint(points).convex_hull.buffer(1) # a polygon 
grid_points = [ shapely.geometry.Point(x,y) for x in range(100) for y in range(100)]
in_poly = np.array([poly.contains(point) for point in grid_points])

#plot
plt.imshow(in_poly.reshape(100,100), origin='lower')
plt.plot(*poly.exterior.xy)

Solution

  • This seems to do what you want - replace this one line (swap y and x in for loops):

    grid_points = [ shapely.geometry.Point(x,y) for y in range(100) for x in range(100)]
    

    Couple of notes:

    My installation of shapely has this module name (geometry spelled differently so you may need to change name in above line):

      import shapely.geometry
    

    And thanks for adding the second plot command - that helped a bunch.

    Something along the way has differing major orders (row-vs-column) so the above line changes to column-major.

    And it may be you'd want to compensate by doing the inverse on the exterior plot.

    (original (with new random shape), updated, with exterior)

    enter image description here enter image description here enter image description here