Description
Bug summary
Trying to create an arc path of 0/360 degrees sometimes results in one of 360/0 degrees due to floating point weirdness.
Code for reproduction
from matplotlib import patches, path, pyplot
fig, ax = pyplot.subplots(ncols=3)
ax[0].add_patch(patches.PathPatch(path.Path.arc(theta1=-90 - 1e-14, theta2=270)))
ax[0].set_title("arc(-90-1e-14, 270), should be a circle")
ax[1].add_patch(patches.PathPatch(path.Path.arc(theta1=-90, theta2=270)))
ax[1].set_title("arc(-90, 270), is a circle")
ax[2].add_patch(patches.PathPatch(path.Path.arc(theta1=-90, theta2=-90 - 1e-14)))
ax[2].set_title("arc(-90, -90-1e-14), should not be a circle")
for a in ax:
a.set_xlim(-1, 1)
a.set_ylim(-1, 1)
a.set_aspect("equal")
pyplot.show()
Actual outcome
Expected outcome
I expect the first plot to be a circle, identical to the second.
I expect the third plot to be empty
Additional information
The location of the bug is not hard to find:
matplotlib/lib/matplotlib/path.py
Lines 951 to 956 in 6fc8169
At runtime the first example becomes (-90 <= -90 - 1e-14) == False
, which therefore skips the +360
bump.
What is much harder is to understand is what the intention is here.
If you can help me to understand what behaviour you'd like, I'd be happy to put together a PR for it.
I think theta2 < theta1
always gives an unexpected result:
- The docstring does not clarify what should happen, therefore my assumption is that it should return an anti-clockwise arc
- The
np.floor
will mean it becomes the angle range [theta1, theta2+360], which gives the third plot which I believe should not be a circle - The special casing only treats
eta2 += 360
, noteta2 -= 360
It would be great if either the docstring could be clarified or a ValueError
raised on unexpected inputs here.
Operating system
No response
Matplotlib Version
3.10.0
Matplotlib Backend
No response
Python version
No response
Jupyter version
No response
Installation
pip