如何在matplotlib中使用set_clip_path()配合多个多边形实现裁剪
问题描述
我正在尝试用多个多边形裁剪点云,但不清楚能否通过plt.axis.set_clip_path()实现该功能。
由于set_clip_path()要求传入Path或Patch类型参数,该如何创建由多个Polygon组成的几何图形?我需要类似plt.MultiPolygon()的功能,但该类实际不存在。我也尝试过将所有Polygon组合为matplotlib.PatchCollection,但无法生效。
以下是期望实现的效果:
以下是我期望的代码写法参考:
import matplotlib.pyplot as plt from matplotlib.collections import PatchCollection import numpy as np fig, ax = plt.subplots() points = np.array([np.random.random(100)*400, np.random.random(100)*100]).T A = plt.Polygon( np.array([( 0, 0),(50,100),(100, 0)]), color='w', ec='k' ) B = plt.Polygon( np.array([(120 , 0),(170 , 100), (220, 0)]), color='w', ec='k' ) C = plt.Polygon( np.array([(240 , 0),(290 , 100), (340, 0)]), color='w', ec='k' ) [ax.add_patch(i) for i in (A,B,C)] ax.scatter(points[:,0], points[:,1], zorder=3).set_clip_path([A,B,C])
实现方案
matplotlib的set_clip_path()仅支持单个Path或Patch类型参数,不需要自定义MultiPolygon类,直接合并多个多边形的路径为单个复合Path即可实现需求,核心用到matplotlib.path.Path.make_compound_path()方法。
可运行完整代码
import matplotlib.pyplot as plt from matplotlib.path import Path import numpy as np fig, ax = plt.subplots(figsize=(8, 3)) # 生成随机点云 points = np.array([np.random.random(100)*400, np.random.random(100)*100]).T # 定义三个裁剪多边形 A = plt.Polygon(np.array([(0, 0), (50, 100), (100, 0)]), color='w', ec='k') B = plt.Polygon(np.array([(120, 0), (170, 100), (220, 0)]), color='w', ec='k') C = plt.Polygon(np.array([(240, 0), (290, 100), (340, 0)]), color='w', ec='k') # 把多边形添加到画布展示 for patch in (A, B, C): ax.add_patch(patch) # 合并多个多边形路径为单个复合路径 compound_path = Path.make_compound_path(A.get_path(), B.get_path(), C.get_path()) # 应用坐标变换,匹配画布的实际坐标体系,避免裁剪位置偏移 compound_path = compound_path.transformed(A.get_transform()) # 绘制点云并设置裁剪路径 scatter = ax.scatter(points[:, 0], points[:, 1], zorder=3) scatter.set_clip_path(compound_path, transform=ax.transData) ax.set_xlim(0, 400) ax.set_ylim(0, 100) plt.show()
关键逻辑说明
- 调用每个Polygon对象的
get_path()方法可以获取其对应的底层路径对象 Path.make_compound_path()可以将多个独立路径合并为一个符合参数要求的复合路径- 必须通过
transformed()方法应用Patch自带的坐标变换,否则路径会和画布上实际显示的多边形位置不匹配,导致裁剪失效
内容的提问来源于stack exchange,提问作者Miguel Gonzalez
相关产品推荐
相关产品推荐

