我一直在使用
matplotlib.path.contains_points()
方法,没有任何数字或图表。根据路径的不同,我得到的结果不一致。在以下示例中,简单的方形路径有效,但椭圆形的较长路径则无效:
import numpy as np
from skimage.draw import ellipse_perimeter
from matplotlib.path import Path
import matplotlib.pyplot as plt
s = 100
squarepath = Path([(0,0), (0, s), (s,s), (s, 0)])
print(squarepath.contains_points([(s/2, s/2)]))
(xv,yv) = ellipse_perimeter(200,360,260,360)
xyverts = np.stack((xv,yv),axis=1)
ellipsepath = Path(xyverts)
pt = (213,300)
print(ellipsepath.contains_points([pt]))
fig,ax = plt.subplots()
plt.scatter(ellipsepath.vertices[:,0],ellipsepath.vertices[:,1])
plt.scatter(pt[0],pt[1])
plt.show()
我在绘制任何内容之前使用
contains_points()
,因此不应该存在任何数据与显示坐标问题,正如有关contains_points()
的其他类似问题中所讨论的那样。这里还会发生什么?
问题在于
ellipse_perimeter
按不定义路径的顺序返回椭圆周长的点。然后在椭圆上的点之间创建顶点。您可以通过将路径绘制为补丁来检查这一点,而不是使用 scatter
:
from matplotlib.patches import PathPatch
ax.add_patch(PathPatch(ellipsepath, facecolor='yellow', lw=1)) # instead of scatter(ellipsepath...)
输出(无需更改代码的任何其他内容):
正如您所看到的,我们只看到了线条(连接整个周边的点),而不是看到
facecolor
指定的黄色椭圆。
patches.Ellipse
并调用 get_path()
。
但是,如果您无法使用 skimage,则必须在创建路径之前对点进行排序:
import numpy as np
from skimage.draw import ellipse_perimeter
from matplotlib.path import Path
import matplotlib.pyplot as plt
from matplotlib.patches import PathPatch
(xv,yv) = ellipse_perimeter(200,360,260,360)
xyverts = list(zip(xv, yv))
pt_top = sorted([(x,y) for x,y in xyverts if y >= 360], key=lambda c: c[0])
pt_bottom = sorted([(x,y) for x,y in xyverts if y < 360], key=lambda c: -c[0])
xyverts = pt_top + pt_bottom
ellipsepath = Path(xyverts)
pt = (213,300)
print(ellipsepath.contains_points([pt]))
fig,ax = plt.subplots()
ax.add_patch(PathPatch(ellipsepath, facecolor='yellow', lw=1))
plt.scatter(pt[0],pt[1])
plt.show()
输出: