如何在Matplotlib中为掩码添加无内部线条的轮廓?
解决方法
要绘制轴对齐且无内部网格线的掩码轮廓,我们可以利用网格边界结合shapely库对单元格多边形进行合并,从而自动去除内部边界。以下是具体实现:
步骤说明
- 生成掩码后,为每个
True单元格创建对应的矩形多边形。 - 使用
shapely的unary_union合并所有多边形,消除内部重叠边界。 - 将合并后的多边形绘制到Matplotlib或Cartopy轴上,支持填充或仅轮廓样式。
完整代码示例
1. 基础Matplotlib实现(填充+轮廓)
import matplotlib.pyplot as plt import numpy as np from shapely.geometry import Polygon from shapely.ops import unary_union # 生成掩码 N = 50 xbound = np.linspace(0, 10, N + 1) ybound = np.linspace(0, 10, N + 1) x = (xbound[:-1] + xbound[1:]) / 2 y = (ybound[:-1] + ybound[1:]) / 2 X, Y = np.meshgrid(x, y) Z = np.exp(-((X - 2.5)**2 + (Y - 2.5)**2)) + np.exp(-2 * ((X - 7.5)**2 + (Y - 6.5)**2)) mask = Z > 0.2 # 创建所有True单元格的多边形 polygons = [] for i in range(mask.shape[0]): for j in range(mask.shape[1]): if mask[i, j]: # 单元格的四个边界坐标 x1, x2 = xbound[j], xbound[j+1] y1, y2 = ybound[i], ybound[i+1] poly = Polygon([(x1, y1), (x2, y1), (x2, y2), (x1, y2)]) polygons.append(poly) # 合并多边形,去除内部边界 unioned_polys = unary_union(polygons) # 绘制结果 fig, ax = plt.subplots(figsize=(8,8)) # 处理单个多边形或多个多边形(如示例中的两个区域) if hasattr(unioned_polys, 'exterior'): # 单个多边形 patch = plt.Polygon(list(unioned_polys.exterior.coords), facecolor='#f9d923', edgecolor='black', linewidth=1.5) ax.add_patch(patch) else: # 多个多边形(MultiPolygon) for poly in unioned_polys.geoms: patch = plt.Polygon(list(poly.exterior.coords), facecolor='#f9d923', edgecolor='black', linewidth=1.5) ax.add_patch(patch) # 设置轴范围和样式 ax.set_xlim(0, 10) ax.set_ylim(0, 10) ax.set_aspect('equal') plt.xlabel('X') plt.ylabel('Y') plt.title('轴对齐掩码轮廓(无内部网格线)') plt.show()
2. 仅绘制轮廓(无填充)
只需修改facecolor为'none':
patch = plt.Polygon(list(poly.exterior.coords), facecolor='none', edgecolor='black', linewidth=2)
3. Cartopy集成示例
如果需要在地图投影上展示,只需将多边形添加到Cartopy轴,并指定坐标变换:
import cartopy.crs as ccrs fig, ax = plt.subplots(figsize=(8,8), subplot_kw={'projection': ccrs.PlateCarree()}) # 设置地图范围(示例使用0-10的坐标,可替换为实际经纬度) ax.set_extent([0, 10, 0, 10], crs=ccrs.PlateCarree()) # 添加合并后的多边形 if hasattr(unioned_polys, 'exterior'): patch = plt.Polygon(list(unioned_polys.exterior.coords), facecolor='#f9d923', edgecolor='black', linewidth=1.5, transform=ccrs.PlateCarree()) ax.add_patch(patch) else: for poly in unioned_polys.geoms: patch = plt.Polygon(list(poly.exterior.coords), facecolor='#f9d923', edgecolor='black', linewidth=1.5, transform=ccrs.PlateCarree()) ax.add_patch(patch) # 添加地图要素(如海岸线,仅实际经纬度场景有效) # ax.coastlines() plt.title('Cartopy上的轴对齐掩码轮廓') plt.show()
优势说明
- 轴对齐边缘:直接使用网格边界,避免了
plt.contour的插值对角线问题。 - 无内部线条:多边形合并自动去除相邻单元格的内部边界。
- 灵活样式:支持填充、仅轮廓等多种展示方式。
- Cartopy兼容:通过坐标变换可轻松集成到地图投影中。
内容的提问来源于stack exchange,提问作者markmuetz
相关产品推荐
相关产品推荐

