# Negate the shapely intersection predicate

I have two Shapely geometries:

• 1 MultiPoint instance named `multipoints`
• 1 Polygon instance named `polygon`

I can compute their `intersection` by: `multipoints.intersection(polyon)` which results in all points that fall inside the polygon.

I'd like to compute their 'non intersection' to get the points which doesn't fall inside the polygon but there is no such: `multipoints.notintersection(polyon)` method: I can use the `symmetric_difference` as: `multipoints.symmetric_difference(polyon)` but this gives a geometry collection with the points I'm searching for + the whole initial polygon (for which I don't care).

I need to have that done in either one line, or a function that can be plugged into a lambda function for applying it all over the rows of a `GeoDataFrame` containing `MultiPoint` geometry instances in each row.

Notice; I can use the boolean result of an `intersects` inside my lambda but it doesn't seem to work when I apply it on a `GeoDataFrame`:

``````gdf['nonintersectingpoints'] = gdf['my_multipoint_column'].apply(
lambda multipoints: multipoints if not multipoints.intersects(polygon) \
else None
)
``````

(result is `None` every where).

One solution is to basically take the difference between the `multipoints` and the resulting intersection between the `multipoints` and the `polygon`, i.e.: `multipoints.difference(multipoints.intersection(polygon))`

Here is a piece of commented code for understanding:

``````import matplotlib.pyplot as plt
from shapely.geometry import Polygon, MultiPoint
import geopandas as gpd

# A Polygon feature
polygon = Polygon([(-0.2, -0.2), (-0.2, 1.2), (1.2, 1.2),
(1.2, -0.2), (-0.2, -0.2) ])

# A MultiPoint feature containing severa points:
multipoints = MultiPoint([(0, 0), (0, 1), (0, -1),
(1, 0), (1, 1), (1, -1),
(-1, 0), (-1, 1), (-1, -1) ])

# Intersecting features:
inter = multipoints.intersection(polygon)

# Here is the trick to get all the non-intersecting features:
noninter = multipoints.difference(multipoints.intersection(polygon))

# Prepare GeoSeries for plotting:
p = gpd.GeoSeries(polygon)     # the Polygon feature
m = gpd.GeoSeries(multipoints) # the MultiPoint feature
i = gpd.GeoSeries(inter)       # the intersecting features
n = gpd.GeoSeries(noninter)    # the non-intersectiing features

# Plotting
fig, ax = plt.subplots(figsize = (5,5))
p.plot(color='skyblue', alpha=0.4, ax=ax)
i.plot(color='red', markersize=256, ax=ax)
# Non-intersecting features are show in green:
n.plot(color='lime', markersize=256, ax=ax)
m.plot(color='blue', markersize=16, ax=ax)
plt.grid(zorder=-9)
plt.show()
``````

And here is the resulting figure: It can also be applied using a lambda as:
`.apply(lambda multipoints: multipoints.difference(multipoints.intersection(poly))`