【问题标题】:Matplotlib path.contains_points returns false for points on some edges but not othersMatplotlib path.contains_points 对某些边上的点返回 false,但在其他边上不返回
【发布时间】:2018-04-19 00:25:53
【问题描述】:

我正在尝试使用 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 值的最后一行。问题在于这种明显的不一致。

【问题讨论】:

  • 也许这里真正的问题是“为什么5 包含在沿垂直边缘线的路径中而不是水平边缘线?”。
  • 我猜这是一个错误。如果更改多边形 polygon[::-1] 的方向,则行为与预期相同,但第 10 行仍显示 True's。
  • 我正要评论说。我会将错误提交到项目页面并报告。
  • 现在可以找到相应的错误报告here

标签: python python-3.x matplotlib


【解决方案1】:

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


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

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

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

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


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

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

因此,如果您为 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 的更多信息。作为一个经验法则:当路径逆时针方向时,正半径会扩大路径,而当路径顺时针方向时,路径会缩小

【讨论】:

  • 我认为它会与此类似,但有没有理由为什么这个限制只存在于顶部边缘?倒数第二行也应受此影响,因为这些点位于 [10,10] [5,10] 边缘,以及具有 True 值的第一列和最后一列。
  • @AlexB 我猜你在这里给出的这个评论是问题中真正有趣的部分,它应该是问题文本本身的一部分。
  • 嗯,这确实很有趣,我同意@ImportanceOfBeingErnest 在问题中强调这一点。实际上只有顶行的行为应该如此。如果您更改多边形的方向,那么[(5,5),(5,10),(10,10),(10,5)] 会按预期运行,尽管半径需要为负才能包含边界。这实际上表明contains_points 在某种程度上对多边形方向很敏感。有点奇怪。
  • 如果您想深入了解方向和半径,您可以查看this answer。但是,我认为这里的这个问题根本与半径无关。
猜你喜欢
  • 2020-01-17
  • 1970-01-01
  • 1970-01-01
  • 2018-10-31
  • 2011-06-05
  • 1970-01-01
  • 1970-01-01
  • 2021-03-26
  • 1970-01-01
相关资源
最近更新 更多