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

使用matplotlib.path.cleaned清理路径出现重复点的问题解决问询

解决matplotlib Path.cleaned()生成重复点的问题

我碰到过这个问题,在matplotlib 2.1.x版本里,Path.cleaned()处理闭合路径时确实会出现这种重复点的bug——它能正确移除对形状无贡献的点(比如你例子里的[0, 0.5]),但在收尾时错误地复制了倒数第二个顶点,导致路径出现冗余的[1, 0]点。

问题根源

这个问题和matplotlib旧版本中路径清理的闭合逻辑有关:当处理闭合路径的最后一段时,代码错误地重复添加了前一个顶点,而没有直接连接回起点。

可行的解决办法

1. 直接升级matplotlib(最推荐)

这个bug在matplotlib 3.0及以上版本已经被修复了。如果你能升级依赖,直接运行:

pip install --upgrade matplotlib

升级后再执行你的原始代码,cleaned()会输出正确的无重复点路径:[[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]。

2. 手动清理重复点(无法升级时用)

如果暂时不能升级版本,可以在调用cleaned()后手动移除重复的顶点,注意要保留路径的闭合状态:

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

fig = plt.figure()
ax = fig.add_subplot(111)
verts = [[0, 0], [0, 0.5], [0, 1], [1, 1], [1, 0], [0, 0]]
codes = [1, 2, 2, 2, 2, 0]

path = Path(verts, codes)
cleaned_path = path.cleaned(simplify=True)

# 手动去重逻辑:跳过重复的非闭合点
fixed_verts = []
fixed_codes = []
seen = set()
for v, c in zip(cleaned_path.vertices, cleaned_path.codes):
    v_tuple = tuple(np.round(v, 9))  # 浮点精度容错
    if c == Path.CLOSEPOLY:
        # 闭合点必须保留
        fixed_verts.append(v)
        fixed_codes.append(c)
        continue
    if v_tuple not in seen:
        seen.add(v_tuple)
        fixed_verts.append(v)
        fixed_codes.append(c)
# 确保路径最终是闭合的
if fixed_codes[-1] != Path.CLOSEPOLY:
    fixed_verts.append(fixed_verts[0])
    fixed_codes.append(Path.CLOSEPOLY)

fixed_path = Path(np.array(fixed_verts), np.array(fixed_codes))

patch = mpatches.PathPatch(fixed_path)
plt.plot(np.asarray(verts)[:, 0], np.asarray(verts)[:, 1], "rx")
ax.add_patch(patch)
plt.show()

3. 自定义路径简化函数

如果你想完全替代cleaned(),可以自己实现一个简单的共线点移除逻辑,针对你的场景更可控:

def simplify_collinear_points(verts, codes):
    simplified = [verts[0]]
    simplified_codes = [codes[0]]
    for i in range(1, len(verts)-1):
        prev = np.array(verts[i-1])
        curr = np.array(verts[i])
        next_v = np.array(verts[i+1])
        # 计算叉积判断三点是否共线
        cross_product = np.cross(next_v - prev, curr - prev)
        if not np.isclose(cross_product, 0, atol=1e-9):
            simplified.append(curr)
            simplified_codes.append(codes[i])
    # 添加最后一个点和闭合代码
    simplified.append(verts[-1])
    simplified_codes.append(codes[-1])
    return np.array(simplified), np.array(simplified_codes)

# 使用自定义函数处理
simplified_verts, simplified_codes = simplify_collinear_points(verts, codes)
fixed_path = Path(simplified_verts, simplified_codes)

总结

优先推荐升级matplotlib到3.0+版本,这样能从根源上解决这个bug;如果受限于环境,手动去重或者自定义简化逻辑也能完美解决你的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:17:55