问题
I am using matplotlib.patches.Polygon to update some colored patches on a graph, and I'm doing it at each iteration of the code. Since I already defined the patches in my code this way, I wanted to use the function contains_point() to resolve whether a point is in the patch or outside of it. So Far what seems working is shapely - but I wouldn't like to do so, I'd rather keep working using matplotlib. The problem arises after calling add_patch(): in this case the patch will return the same coordinates but the function contains_point() will not return the correct value
import matplotlib.pyplot as plt
import matplotlib.patches as patches
from matplotlib import gridspec
import numpy as np
let's define some axes on which we want to add the patches
gs = gridspec.GridSpec(1,1)
axx = [plt.subplot(g) for g in gs]
Let's see what type is axx:
In[84]: axx
Out[84]: [<matplotlib.axes._subplots.AxesSubplot at 0x7fd4b3409cd0>]
Let's now define a patch b
with vertexes v
v =
np.array([[ 6.89 , -10.00907385],
[ 5.11 , -10.00907385],
[ 5.11 , -14.68307385],
[ 6.89 , -14.68307385],
[ 6.89 , -10.00907385]])
b = [patches.Polygon(v, color = (0,0,1))]
we can test that:
In[86]: b[0].contains_point((5.5,-12))
Out[86]: True
Let's now add the patch to the subplot previously initialized
axx[0].add_patch(b[0])
let's test again if the same point (5.5,-12) falls in patch b
In[88]: b[0].contains_point((5.5,-12))
Out[88]: False
In[89]: b[0].get_xy()
Out[89]:
array([[ 6.89 , -10.00907385],
[ 5.11 , -10.00907385],
[ 5.11 , -14.68307385],
[ 6.89 , -14.68307385],
[ 6.89 , -10.00907385]])
回答1:
Once the polygon is added to the axes, contains_point
uses the internal coordinates to determine whether some point is contained in the polygon.
You hence need to transform your point
to the screen coordinate system first and then query if it is contained in the patch poly
,
poly.contains_point(ax.transData.transform(point))
Alternatvely, use the patches' path' contains_point
method, without specifying any transform to it,
poly.get_path().contains_point(point)
Complete example code:
import matplotlib.pyplot as plt
import matplotlib.patches as patches
import numpy as np
a = np.array([[2,6],[4,6],[4,8],[2,8],[2,6]])
poly = patches.Polygon(a)
point = (3,7)
cp1 = poly.contains_point(point)
print (cp1) # prints True
fig,ax = plt.subplots()
ax.add_patch(poly)
cp2 = poly.contains_point(ax.transData.transform(point))
print(cp2) # prints True
cp3 = poly.get_path().contains_point(point)
print(cp3) # prints True
ax.scatter(point[0],point[1], color="crimson", zorder=6)
plt.show()
来源:https://stackoverflow.com/questions/49098942/matplotlib-patches-polygon-function-contains-point-fails-to-resolve-a-point-in