python - Matplotlib path.contains_points 对某些边上的点返回 false 而对其他边不返回

标签 python python-3.x matplotlib

我正在尝试使用 Matplotlib 查找多边形路径中包含的所有点,但它似乎遗漏了一些点。更具体地说,我的路径是一个矩形,并且点位于底层统一网格上。在下面的测试脚本中,它不会将位于多边形顶线上的点视为多边形的一部分,但会考虑其余边上的点。

代码:

import matplotlib.path as mpltPath

polygon = [(5,5),(10,5),(10,10),(5,10)]
width =11
height =11

points = [[0,0],[1,0],[2,0],[3,0],[4,0],[5,0],[6,0],[7,0],[8,0],[9,0],[10,0],[11,0], \
          [0,1],[1,1],[2,1],[3,1],[4,1],[5,1],[6,1],[7,1],[8,1],[9,1],[10,1],[11,1],\
          [0,2],[1,2],[2,2],[3,2],[4,2],[5,2],[6,2],[7,2],[8,2],[9,2],[10,2],[11,2],\
          [0,3],[1,3],[2,3],[3,3],[4,3],[5,3],[6,3],[7,3],[8,3],[9,3],[10,3],[11,3],\
          [0,4],[1,4],[2,4],[3,4],[4,4],[5,4],[6,4],[7,4],[8,4],[9,4],[10,4],[11,4],\
          [0,5],[1,5],[2,5],[3,5],[4,5],[5,5],[6,5],[7,5],[8,5],[9,5],[10,5],[11,5],\
          [0,6],[1,6],[2,6],[3,6],[4,6],[5,6],[6,6],[7,6],[8,6],[9,6],[10,6],[11,6],\
          [0,7],[1,7],[2,7],[3,7],[4,7],[5,7],[6,7],[7,7],[8,7],[9,7],[10,7],[11,7],\
          [0,8],[1,8],[2,8],[3,8],[4,8],[5,8],[6,8],[7,8],[8,8],[9,8],[10,8],[11,8],\
          [0,9],[1,9],[2,9],[3,9],[4,9],[5,9],[6,9],[7,9],[8,9],[9,9],[10,9],[11,9],\
          [0,10],[1,10],[2,10],[3,10],[4,10],[5,10],[6,10],[7,10],[8,10],[9,10],[10,10],[11,10],\
          [0,11],[1,11],[2,11],[3,11],[4,11],[5,11],[6,11],[7,11],[8,11],[9,11],[10,11],[11,11]]


path = mpltPath.Path(polygon)
inside = path.contains_points(points)
print(inside)

照原样,上面的代码将返回

[False False False False False False False False False False False False
 False False False False False False False False False False False False
 False False False False False False False False False False False False
 False False False False False False False False False False False False
 False False False False False False False False False False False False
 False False False False False False False False False False False False
 False False False False False  True  True  True  True  True  True False
 False False False False False  True  True  True  True  True  True False
 False False False False False  True  True  True  True  True  True False
 False False False False False  True  True  True  True  True  True False
 False False False False False  True  True  True  True  True  True False
 False False False False False False False False False False False False]

我希望结果的第 5 行包含 True 值,就像它后面的那些一样。如果我将多边形中的坐标从 5 更改为 4.9,那么我确实会得到我期望的结果。

我假设这与滥用或误解函数有关,但我不太确定那可能是什么或如何。

编辑:有人提出 contains_points对于落在多边形边缘的点,应该返回 False。在我的示例中,我们看到顶部边缘 [5,5]-[10,5] 有这种行为,但其他边缘没有(即 [5,5]-[5,10]、[5,10]- [10,10] 和 [10,10]-[10,5])。这三个其他边对应于上面示例输出中具有 True 值的第一列和最后一列以及包含 True 值的最后一行。正是这种明显的不一致才是问题所在。

最佳答案

更新:现在是一个开放的 issue in matplotlib .


排除边界线可能是像 contains_points 这样的函数的预期行为. 但是,在这种情况下,多边形边界上的点没有以一致的方式处理:

在您给出的示例中,第 5 行表示排除边界上的点,但第 5 行和第 10 行和第 10 行表示包含边界点。

使用 polygon[::-1] 绘制路径,因此反向方向会导致所有边界的预期行为,但第 10 行再次应用包含。

对我来说,这里没有明显的逻辑模式。但即使有,这种行为也确实令人困惑,应该予以修复。


现在您仍然可以通过避免将点放置在多边形的边界上来获得所需的行为。您可以使用 contains_pointsradius 属性来做到这一点功能:

radius allows the path to be made slightly larger or smaller.

因此,如果您像这样为 radius 属性提供一些小的、正的或负的值:

# ...
path = mpltPath.Path(polygon)
inside = path.contains_points(points,radius=0.1)

print(inside)

你得到:

[False False False False False False False False False False False False
 False False False False False False False False False False False False
 False False False False False False False False False False False False
 False False False False False False False False False False False False
 False False False False False False False False False False False False
 False False False False False  True  True  True  True  True  True False
 False False False False False  True  True  True  True  True  True False
 False False False False False  True  True  True  True  True  True False
 False False False False False  True  True  True  True  True  True False
 False False False False False  True  True  True  True  True  True False
 False False False False False  True  True  True  True  True  True False
 False False False False False False False False False False False False]

请注意,半径是正数还是负数取决于方向。您可以找到有关此的更多信息 here .根据经验:正半径会在路径逆时针方向时扩展路径,而在路径顺时针方向时收缩路径

关于python - Matplotlib path.contains_points 对某些边上的点返回 false 而对其他边不返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47143754/

相关文章:

python - 如何使用 Python 2.7 和 Robot Framework 2.9 开始使用 Edge webdriver

python - __getitem__ 方法接收 int 而不是 slice obj

python - 我的 Python 代码中的内存问题

python - 如何在 Python 中屏蔽二维列表?

python - Pylab/Matplotlib 将多个饼图合并为一个 PDF

python - 根据 Matplotlib 中的预计数数据绘制直方图

python - 从两个不等长的 numpy 数组中选择元素

python - 如何使用 xlsxwriter 格式化索引列?

python - 为什么 Python 需要永远评估 1**4**4**4**4?

python - 如何更改感兴趣区域的 pyplot 背景颜色?