You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Matplotlib如何裁剪多边形外的线条 可否用numpy掩码实现?

解决方案

可以通过numpy掩码实现裁剪,也可以使用Matplotlib内置的路径裁剪功能实现更高效率的处理,两种方案的实现代码如下:

方法1:Matplotlib内置路径裁剪(最简便)

不需要额外计算几何逻辑,直接将多边形作为裁剪路径绑定到竖线对象即可,适配任意形状的多边形:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.path import Path

x = [10,15.5,12.5,7.5,5,10]
y = [15,10,5,5,10,15]

fig, ax = plt.subplots()
ax.fill_between(x,y, facecolor="blue", alpha=0.25)
ax.axis("equal")

# 生成多边形路径对象
poly_coords = np.column_stack([x, y])
poly_path = Path(poly_coords)

myinterval = 1.5
xvals = np.arange(min(x), max(x)+1, myinterval)
for i in xvals:
    # 获取竖线对象,绑定裁剪路径
    line, = ax.plot([i,i], [0,20], color='red')
    line.set_clip_path(poly_path, transform=ax.transData)

plt.show()

方法2:Numpy掩码实现(符合要求的技巧)

核心思路是对每条竖线的y坐标做范围掩码,只保留落在多边形内部的坐标点再绘制:

import numpy as np
import matplotlib.pyplot as plt

x = [10,15.5,12.5,7.5,5,10]
y = [15,10,5,5,10,15]

fig, ax = plt.subplots()
ax.fill_between(x,y, facecolor="blue", alpha=0.25)
ax.axis("equal")

# 拆分多边形的上下边界并按x排序,用于后续插值计算
lower_bound = np.array([[5,10], [7.5,5], [12.5,5], [15.5,10]])
lower_bound = lower_bound[lower_bound[:,0].argsort()]
upper_bound = np.array([[5,10], [10,15], [15.5,10]])
upper_bound = upper_bound[upper_bound[:,0].argsort()]

myinterval = 1.5
xvals = np.arange(min(x), max(x)+1, myinterval)
y_sample = np.linspace(0, 20, 200) # 竖线的y坐标采样

for i in xvals:
    # 插值得到当前x位置的多边形上下y边界
    y_low = np.interp(i, lower_bound[:,0], lower_bound[:,1])
    y_high = np.interp(i, upper_bound[:,0], upper_bound[:,1])
    # 生成掩码,只保留范围内的y坐标
    mask = (y_sample >= y_low) & (y_sample <= y_high)
    y_clip = y_sample[mask]
    # 绘制裁剪后的竖线
    ax.plot(np.full_like(y_clip, i), y_clip, color='red')

plt.show()

两种方案对比

  • 路径裁剪方案代码更简洁,不需要处理多边形的几何逻辑,复杂多边形场景下性能更优
  • numpy掩码方案灵活度更高,适合需要自定义裁剪规则、后续需要对裁剪后的数据做额外计算的场景

内容的提问来源于stack exchange,提问作者a11

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 07:54:00