Matplotlib Shapely – Plotting MultiPolygons

matplotlibpythonshapely

I have few polygons or boxes. Ones intersect each other but some are isolated. For example I have free figures:

import shapely.geometry as sg
import shapely.ops as so
import matplotlib.pyplot as plt
    
r1 = sg.Polygon([(0,0),(0,1),(1,1),(1,0),(0,0)])
r2 = sg.box(0.5,0.5,1.5,1.5)
r3 = sg.box(4,4,5,5)

First two are intersected and r3 is on some distance from them. I unite them via cascaded_union:

new_shape = so.cascaded_union([r1, r2, r3])

Then I try to plot it (one united figure of r1 and r2 and one distanced box r3)

xs, ys = new_shape.exterior.xy
fig, axs = plt.subplots()
axs.fill(xs, ys, alpha=0.5, fc='r', ec='none')
plt.show()

Instead of plot I receive an AttributeError: 'MultiPolygon' object has no attribute 'exterior'.
Is there a pythonic way to display a multipolygon or to iterate through it and draw its parts?

Best Answer

Shapely Polygon object has attribute exterior. Shapely MultiPolygon object has Polygon object sequence. You should iterate over those polygons. You can do that using attribute geoms of MultiPolygon.

Use this way:

import shapely.geometry as sg
import shapely.ops as so
import matplotlib.pyplot as plt

r1 = sg.Polygon([(0,0),(0,1),(1,1),(1,0),(0,0)])
r2 = sg.box(0.5,0.5,1.5,1.5)
r3 = sg.box(4,4,5,5)

new_shape = so.cascaded_union([r1, r2, r3])
fig, axs = plt.subplots()
axs.set_aspect('equal', 'datalim')

for geom in new_shape.geoms:    
    xs, ys = geom.exterior.xy    
    axs.fill(xs, ys, alpha=0.5, fc='r', ec='none')

plt.show()

enter image description here