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

matplotlib.patches.Polygon的contains_point()方法add_patch后失效问题

嘿,我刚好踩过这个坑!你遇到的问题核心是坐标系统不匹配——matplotlib.patches.Polygon的contains_point()默认是基于屏幕显示坐标(像素)判断的,但你大概率是传入了数据坐标,而且调用add_patch()后,补丁和坐标轴的变换系统绑定,这就直接导致判断逻辑失效了。

下面给你两种靠谱的解决方法,全程只用matplotlib,完全不用依赖shapely:

第一步:理解问题根源

当你把Polygon通过add_patch()添加到轴(Axes)后,补丁的顶点存储的是数据坐标,但contains_point()默认接收的是经过轴变换后的屏幕像素坐标。直接传数据点进去,相当于用数据坐标系的数值去匹配像素位置,结果肯定不对。

第二步:两种正确的判断方式

方式1:手动转换数据点到显示坐标

利用轴的transData变换,把你的数据点转换成屏幕坐标后再传入判断:

import matplotlib.pyplot as plt
from matplotlib.patches import Polygon

# 初始化图表和轴
fig, ax = plt.subplots()
# 创建多边形补丁(用数据坐标定义顶点)
poly_verts = [(0, 0), (2, 0), (2, 2), (0, 2)]
poly = Polygon(poly_verts, facecolor="#a8e6cf")
ax.add_patch(poly)
# 设置轴范围确保多边形可见
ax.set_xlim(-0.5, 2.5)
ax.set_ylim(-0.5, 2.5)

# 要判断的目标数据点
test_point = (1, 1)

# 把数据点转换为屏幕显示坐标
display_point = ax.transData.transform(test_point)
# 执行判断
is_inside = poly.contains_point(display_point)
print(f"点{test_point}是否在多边形内:{is_inside}")  # 会返回True

方式2:直接给contains_point()传入变换参数

contains_point()本身支持传入transform参数,指定你的点使用的坐标系统,它会自动帮你完成转换:

# 沿用上面的初始化代码...

# 直接传入数据点,同时指定坐标变换为轴的transData
is_inside = poly.contains_point(test_point, transform=ax.transData)
print(f"点{test_point}是否在多边形内:{is_inside}")  # 同样返回True

迭代更新补丁后的注意事项

如果你是逐迭代更新补丁的顶点(比如动态修改多边形形状),要记住:

  • 不要直接修改补丁的verts属性,一定要用poly.set_verts(new_verts)方法,这样matplotlib会同步更新内部的变换缓存。
  • 更新后的判断逻辑和上面完全一致,不需要额外调整——因为补丁始终绑定着轴的transData变换,只要用对坐标系统就没问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 07:11:08