如何用Python Matplotlib绘制阈值以上网格的外边缘
Matplotlib伪彩图高亮超阈值网格外边缘解决方案
我用Matplotlib的pcolor函数绘制了2D伪彩图,希望高亮显示数值超过阈值的网格的外边缘。目前的代码会给每个符合条件的网格绘制完整的矩形边框,导致相邻网格的重叠边框重复显示,需要将这些矩形合并为单个形状后再绘制外边缘。
原代码:
import numpy as np import matplotlib.pyplot as plt from matplotlib.patches import Rectangle z = np.array([[0,0,0,1,1],[1,0,6,1,3],[1,7,10,1,2],[1,1,0,0,2],[0,0,2,1,2]]) threshold = 5 fig = plt.figure(figsize =(12, 10)) ax = fig.add_axes([0, 0, 1, 1]) c = ax.pcolor(z, cmap = 'viridis') for i in range(z.shape[0]): for j in range(z.shape[1]): if z[i, j] > threshold: ax.add_patch(Rectangle((j, i), 1, 1, fc='none', ec='crimson', lw=5)) ax.axis('off') fig.colorbar(c, ax=ax) plt.show()
解决方案
可以借助shapely库合并相邻的矩形多边形,再用Matplotlib的PathPatch绘制合并后的轮廓,具体步骤如下:
- 安装shapely库(如果未安装):
pip install shapely
- 修改后的代码:
import numpy as np import matplotlib.pyplot as plt from matplotlib.patches import PathPatch from matplotlib.path import Path from shapely.geometry import Polygon from shapely.ops import unary_union z = np.array([[0,0,0,1,1],[1,0,6,1,3],[1,7,10,1,2],[1,1,0,0,2],[0,0,2,1,2]]) threshold = 5 fig = plt.figure(figsize=(12, 10)) ax = fig.add_axes([0, 0, 1, 1]) c = ax.pcolor(z, cmap='viridis') # 收集所有符合条件的网格对应的多边形 polygons = [] for i in range(z.shape[0]): for j in range(z.shape[1]): if z[i, j] > threshold: # 定义网格的四个顶点(左下角为(j,i),宽1高1) coords = [(j, i), (j+1, i), (j+1, i+1), (j, i+1)] polygons.append(Polygon(coords)) # 合并所有多边形为整体形状 merged_polygon = unary_union(polygons) # 将Shapely多边形转换为Matplotlib Path对象 def polygon_to_path(polygon): vertices = [] codes = [] for geom in polygon.geoms: coords = list(geom.exterior.coords) vertices.extend(coords) # 配置路径指令:移动到起点、绘制线段、闭合路径 codes.extend([Path.MOVETO] + [Path.LINETO]*(len(coords)-2) + [Path.CLOSEPOLY]) return Path(vertices, codes) # 处理合并后的多边形(可能是单个多边形或多个多边形的集合) if merged_polygon.geom_type == 'MultiPolygon': path = polygon_to_path(merged_polygon) else: coords = list(merged_polygon.exterior.coords) path = Path(coords, [Path.MOVETO] + [Path.LINETO]*(len(coords)-2) + [Path.CLOSEPOLY]) # 添加合并后的外边缘到轴上 patch = PathPatch(path, facecolor='none', edgecolor='crimson', linewidth=5) ax.add_patch(patch) ax.axis('off') fig.colorbar(c, ax=ax) plt.show()
代码说明
- 遍历符合条件的网格,为每个网格创建Shapely的
Polygon对象,记录四个顶点坐标 - 使用
unary_union将所有相邻或重叠的多边形合并为整体形状,消除内部重复边框 - 编写
polygon_to_path函数,将Shapely多边形转换为Matplotlib可识别的Path对象 - 通过
PathPatch绘制合并后的形状外边缘,实现只显示整体轮廓的效果
内容的提问来源于stack exchange,提问作者mgm
相关产品推荐
相关产品推荐

