Issue
Why does changing the plotting parameters of matplotlib.patches
contains_point()
change the value to be nonsensical? For example:
import matplotlib.patches as mpatches
print(mpatches.Circle((0,0), radius=1, ec='r').contains_point((0,1.5)))
print(mpatches.Circle((0,0), radius=1).contains_point((0,1.5)))
returns True
for the first line, and False
for the second - when obviously a unit circle centered at (0,0)
does not contain (0, 1.5)
.
Solution
In the contains_point
function you could specify a radius
parameter so that all points enclosed between the borders of the patch and half the radius specified are also considered in the area. When you specify an edgecolor
a default linewidth
is set to 1 and this is going to modify the radius
parameter in the contains_point
function. In the source code of this function in fact you can see that there's a call to a _process_radius
function that modify the radius
parameter of contains_point
to linewidth. This behaviour is documented in the docs of the contains_point
function of the general path object:
The path is extended tangentially by radius/2; i.e. if you would draw the path with a linewidth of radius, all points on the line would still be considered to be contained in the area. Conversely, negative values shrink the area: Points on the imaginary line will be considered outside the area.
From this we can understand the behaviour you are experimenting. To solve you can:
set_edgecolor
after checked for points- always specify
radius=0
in thecontains_point
function
###### Solution 1 ######
import matplotlib.patches as mpatches
import matplotlib.pyplot as plt
circle_ec = mpatches.Circle((0,0), radius=1)
circle = mpatches.Circle((0,0), radius=1)
point = (0,1.5)
print(circle_ec.contains_point(point, radius = 0)) # prints False
print(circle.contains_point(point)) # prints False
circle_ec.set_edgecolor('r')
###### Solution 2 #######
import matplotlib.patches as mpatches
import matplotlib.pyplot as plt
circle_ec = mpatches.Circle((0,0), radius=1, ec='r')
circle = mpatches.Circle((0,0), radius=1)
point = (0,1.5)
print(circle_ec.contains_point(point, radius = 0)) # prints False
print(circle.contains_point(point)) # prints False
Anyway I think that is an unwanted behaviour since linewidth
is specified in points and not in data coords. Opened an issue here.
Answered By - Aelius
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.