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

Ale*_*x B 6 python matplotlib python-3.x

我正在尝试使用 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)
Run Code Online (Sandbox Code Playgroud)

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

[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]
Run Code Online (Sandbox Code Playgroud)

我希望结果的第 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 值的最后一行。正是这种明显的不一致才是问题所在。

joj*_*ojo 5

更新:现在是matplotlib 中的一个未解决的问题


排除边界上的线条可能是contains_points 之类的函数的预期行为。但是,在这种情况下,多边形边界上的点不会以一致的方式处理

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

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

对我来说,这里没有明显的逻辑模式。但即使有,这种行为肯定会令人困惑,应该修复。


现在,您仍然可以通过避免放置在多边形边界上的点来获得所需的行为。您可以使用contains_points函数的radius属性执行此操作:

半径允许路径稍微变大或变小。

因此,如果您为半径属性提供一些小的、正值或负值,如下所示:

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

print(inside)
Run Code Online (Sandbox Code Playgroud)

你得到:

[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]
Run Code Online (Sandbox Code Playgroud)

请注意,半径是正数还是负数取决于方向。您可以在此处找到更多相关信息。根据经验:当路径逆时针方向移动时,正半径会扩大路径,而当路径顺时针方向时,路径会缩小