如何使用 Matplotlib 绘制 Shapely 多边形和对象?
How do I plot Shapely polygons and objects using Matplotlib?
我想将 Shapely 用于我的计算几何项目。为此,我需要能够可视化和显示多边形、线条和其他几何对象。我尝试为此使用 Matplotlib,但遇到了问题。
from shapely.geometry import Polygon
import matplotlib.pyplot as plt
polygon1 = Polygon([(0,5),
(1,1),
(3,0),
])
plt.plot(polygon1)
plt.show()
我希望能够在绘图中显示此多边形。我将如何更改我的代码来执行此操作?
这可能有点矫枉过正,但作为其他好评的替代方案,我会添加一个安装 QGIS 的选项 - 一个用于处理几何图形的免费软件。您需要做的就是将几何图形保存为形状文件 (.shp)、geoJSON 或任何其他格式,然后使用 QGIS 打开它。如果您正在计划一个大项目,最后可能比使用 matplotlib 更方便。
使用:
import matplotlib.pyplot as plt
x,y = polygon1.exterior.xy
plt.plot(x,y)
或者,更简洁:
plt.plot(*polygon1.exterior.xy)
如果您的数据在 .shp
文件中,我会推荐 geopandas:
import geopandas as gpd
import matplotlib.pyplot as plt
shapefile = gpd.read_file("path/to/shapes.shp")
shapefile.plot()
plt.show()
有点晚了,但我发现最方便的方法是按照上面的建议使用 Geopandas,但无需先写入文件。
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()
的文档
我厌倦了 Matplotlib 创建这些绘图图像的简陋 API,所以我创建了自己的库。 Python 模块称为 WKTPlot, and uses Bokeh 以制作数据的交互式图表。我有关于如何绘制 WKT 字符串数据以及来自 Shapefile 的数据的示例。
它支持所有最匀称的几何类型:
- 点
- 多点
- 线串
- 多线串
- 线性环
- 多边形
- 多边形
- 几何集合
这是一个使用 matplotlib 补丁的解决方案,它也解决了漏洞:
import numpy as np
import shapely.geometry as sg
import matplotlib.pyplot as plt
import matplotlib.patches as patches
def add_polygon_patch(coords, ax, fc='blue'):
patch = patches.Polygon(np.array(coords.xy).T, fc=fc)
ax.add_patch(patch)
border = [(-10, -10), (-10, 10), (10, 10), (10, -10)] # Large square
holes = [
[(-6, -2), (-6, 2), (-2, 2), (-2, -2)], # Square hole
[(2, -2), (4, 2), (6, -2)] # Triangle hole
]
region = sg.Polygon(shell=border, holes=holes)
fig, ax = plt.subplots(1, 1)
add_polygon_patch(region.exterior, ax)
for interior in region.interiors:
add_polygon_patch(interior, ax, 'white')
ax.axis('equal')
plt.show()
您还可以'follow along'使用 Shapely 用户手册中的源代码:(单击“源代码”)。
此处提供的'source code'不是实际的Shapely源代码,而是用户手册中用于创建示例的代码。使用 Shapely 用户手册中的这个 'example code' 可以让您快速创建具有相同友好风格的图像。
您将需要 'figures' 模块,它只是一个简短、非常简单的 python 文件,来自:https://github.com/Toblerity/Shapely/blob/main/docs/code/figures.py. (Taken from per https://gis.stackexchange.com/questions/362492/shapely-examples-use-figures-what-is-this-library)
几何可以是 Point
、LineString
、Polygon
,以及它们的 collection 版本 MultiPoint
、MultiLineString
、MultiPolygon
.
点
只需将坐标传递给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)
线串
只需将 x 和 y collection 传递给 pyplot
。它们是使用 xy
属性获得的。此属性 returns 类似于:
(array('d', [3.0, 2.0, 9.0]), array('d', [6.0, -1.0, 4.0]))
并且可以这样使用:
ax.plot(line.xy[0], line.xy[1])
ax.plot(*line.xy) # Equivalent
多边形
对于Polygon
,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
这样使用:
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
对于Multi
- collections,只需在每个元素上调用绘图函数即可。
我想将 Shapely 用于我的计算几何项目。为此,我需要能够可视化和显示多边形、线条和其他几何对象。我尝试为此使用 Matplotlib,但遇到了问题。
from shapely.geometry import Polygon
import matplotlib.pyplot as plt
polygon1 = Polygon([(0,5),
(1,1),
(3,0),
])
plt.plot(polygon1)
plt.show()
我希望能够在绘图中显示此多边形。我将如何更改我的代码来执行此操作?
这可能有点矫枉过正,但作为其他好评的替代方案,我会添加一个安装 QGIS 的选项 - 一个用于处理几何图形的免费软件。您需要做的就是将几何图形保存为形状文件 (.shp)、geoJSON 或任何其他格式,然后使用 QGIS 打开它。如果您正在计划一个大项目,最后可能比使用 matplotlib 更方便。
使用:
import matplotlib.pyplot as plt
x,y = polygon1.exterior.xy
plt.plot(x,y)
或者,更简洁:
plt.plot(*polygon1.exterior.xy)
如果您的数据在 .shp
文件中,我会推荐 geopandas:
import geopandas as gpd
import matplotlib.pyplot as plt
shapefile = gpd.read_file("path/to/shapes.shp")
shapefile.plot()
plt.show()
有点晚了,但我发现最方便的方法是按照上面的建议使用 Geopandas,但无需先写入文件。
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()
我厌倦了 Matplotlib 创建这些绘图图像的简陋 API,所以我创建了自己的库。 Python 模块称为 WKTPlot, and uses Bokeh 以制作数据的交互式图表。我有关于如何绘制 WKT 字符串数据以及来自 Shapefile 的数据的示例。
它支持所有最匀称的几何类型:
- 点
- 多点
- 线串
- 多线串
- 线性环
- 多边形
- 多边形
- 几何集合
这是一个使用 matplotlib 补丁的解决方案,它也解决了漏洞:
import numpy as np
import shapely.geometry as sg
import matplotlib.pyplot as plt
import matplotlib.patches as patches
def add_polygon_patch(coords, ax, fc='blue'):
patch = patches.Polygon(np.array(coords.xy).T, fc=fc)
ax.add_patch(patch)
border = [(-10, -10), (-10, 10), (10, 10), (10, -10)] # Large square
holes = [
[(-6, -2), (-6, 2), (-2, 2), (-2, -2)], # Square hole
[(2, -2), (4, 2), (6, -2)] # Triangle hole
]
region = sg.Polygon(shell=border, holes=holes)
fig, ax = plt.subplots(1, 1)
add_polygon_patch(region.exterior, ax)
for interior in region.interiors:
add_polygon_patch(interior, ax, 'white')
ax.axis('equal')
plt.show()
您还可以'follow along'使用 Shapely 用户手册中的源代码:(单击“源代码”)。
此处提供的'source code'不是实际的Shapely源代码,而是用户手册中用于创建示例的代码。使用 Shapely 用户手册中的这个 'example code' 可以让您快速创建具有相同友好风格的图像。
您将需要 'figures' 模块,它只是一个简短、非常简单的 python 文件,来自:https://github.com/Toblerity/Shapely/blob/main/docs/code/figures.py. (Taken from per https://gis.stackexchange.com/questions/362492/shapely-examples-use-figures-what-is-this-library)
几何可以是 Point
、LineString
、Polygon
,以及它们的 collection 版本 MultiPoint
、MultiLineString
、MultiPolygon
.
点
只需将坐标传递给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)
线串
只需将 x 和 y collection 传递给 pyplot
。它们是使用 xy
属性获得的。此属性 returns 类似于:
(array('d', [3.0, 2.0, 9.0]), array('d', [6.0, -1.0, 4.0]))
并且可以这样使用:
ax.plot(line.xy[0], line.xy[1])
ax.plot(*line.xy) # Equivalent
多边形
对于Polygon
,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
这样使用:
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
对于Multi
- collections,只需在每个元素上调用绘图函数即可。