How do I plot Shapely polygons and objects using Matplotlib?
Geometries can be Point
, LineString
, Polygon
, and their collection versions MultiPoint
, MultiLineString
, MultiPolygon
.
Point
Just pass the coordinates to pyplot
:
points = (point1, point2, point3, point3D)
xs = [point.x for point in points]
ys = [point.y for point in points]
fig, ax = plt.subplots()
ax.set_aspect('equal')
ax.scatter(xs, ys)
LineString
Just pass the x and y collections to pyplot
. They are obtained using xy
attribute. This attribute returns something like:
(array('d', [3.0, 2.0, 9.0]), array('d', [6.0, -1.0, 4.0]))
and can be used this way:
ax.plot(line.xy[0], line.xy[1])
ax.plot(*line.xy) # Equivalent
Polygon
For Polygon
, the currently accepted answer indeed works only for degraded polygons, that is polygons without holes. Here is a version working for any polygon with usual keywords for colors and other attributes. It's not my design, it's just adapted from GeoPandas source
import numpy as np
from matplotlib.path import Path
from matplotlib.patches import PathPatch
from matplotlib.collections import PatchCollection
# Plots a Polygon to pyplot `ax`
def plot_polygon(ax, poly, **kwargs):
path = Path.make_compound_path(
Path(np.asarray(poly.exterior.coords)[:, :2]),
*[Path(np.asarray(ring.coords)[:, :2]) for ring in poly.interiors])
patch = PathPatch(path, **kwargs)
collection = PatchCollection([patch], **kwargs)
ax.add_collection(collection, autolim=True)
ax.autoscale_view()
return collection
It is used this way:
from shapely.geometry import Polygon
import matplotlib.pyplot as plt
# Input polygon with two holes
# (remember exterior point order is ccw, holes cw else
# holes may not appear as holes.)
polygon = Polygon(shell=((0,0),(10,0),(10,10),(0,10)),
holes=(((1,3),(5,3),(5,1),(1,1)),
((9,9),(9,8),(8,8),(8,9))))
fig, ax = plt.subplots()
plot_polygon(ax, polygon, facecolor='lightblue', edgecolor='red')
Collections
For Multi
- collections, just call the plot function on each element.
A little late but I find the most convenient way to do this is with Geopandas as suggested above but without writing to a file first.
from shapely.geometry import Polygon
import matplotlib.pyplot as plt
import geopandas as gpd
polygon1 = Polygon([(0,5),
(1,1),
(3,0),
])
p = gpd.GeoSeries(polygon1)
p.plot()
plt.show()
Checkout the docs for Geopandas.GeoSeries
If your data is in a .shp
file, I would recommend geopandas:
import geopandas as gpd
import matplotlib.pyplot as plt
shapefile = gpd.read_file("path/to/shapes.shp")
shapefile.plot()
plt.show()
Use:
import matplotlib.pyplot as plt
x,y = polygon1.exterior.xy
plt.plot(x,y)
Or, more succinctly:
plt.plot(*polygon1.exterior.xy)