Skip to content

Computing the bounding box of a degenerate polygon throws an error #17975

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
antonio-rojas opened this issue Jul 20, 2020 · 5 comments · Fixed by #17982
Closed

Computing the bounding box of a degenerate polygon throws an error #17975

antonio-rojas opened this issue Jul 20, 2020 · 5 comments · Fixed by #17982
Assignees
Milestone

Comments

@antonio-rojas
Copy link

With 3.3.0, computing the bounding box of a degenerate (one-point) polygon throws an error

Code for reproduction

from matplotlib.patches import Polygon                                                                                                            
pp=Polygon([[0.,0.]])                                                                                                                             
pp.get_extents()                                                                                                                                  

Actual outcome

ValueError                                Traceback (most recent call last)
<ipython-input-3-1312a177eac2> in <module>
----> 1 pp.get_extents()

/usr/lib/python3.8/site-packages/matplotlib/patches.py in get_extents(self)
    254         Return the `Patch`'s axis-aligned extents as a `~.transforms.Bbox`.
    255         """
--> 256         return self.get_path().get_extents(self.get_transform())
    257 
    258     def get_transform(self):

/usr/lib/python3.8/site-packages/matplotlib/path.py in get_extents(self, transform, **kwargs)
    590             self = transform.transform_path(self)
    591         bbox = Bbox.null()
--> 592         for curve, code in self.iter_bezier(**kwargs):
    593             # places where the derivative is zero can be extrema
    594             _, dzeros = curve.axis_aligned_extrema()

/usr/lib/python3.8/site-packages/matplotlib/path.py in iter_bezier(self, **kwargs)
    442             if first_vert is None:
    443                 if code != Path.MOVETO:
--> 444                     raise ValueError("Malformed path, must start with MOVETO.")
    445             if code == Path.MOVETO:  # a point is like "CURVE1"
    446                 first_vert = verts

ValueError: Malformed path, must start with MOVETO.

Expected outcome

With 3.2:

Bbox([[inf, inf], [-inf, -inf]])

Matplotlib version

  • Operating system: Linux x86_64
  • Matplotlib version: 3.3.0
  • Matplotlib backend (print(matplotlib.get_backend())): Qt5Agg
  • Python version: 3.8.4
@tacaswell tacaswell added this to the v3.3.1 milestone Jul 20, 2020
@tacaswell
Copy link
Member

attn @brunobeltran

@brunobeltran
Copy link
Contributor

brunobeltran commented Jul 20, 2020

The new path extents code revealed an existing bug in the code that generates Polygon paths. For this case it documents that it should return

Path([[0,0], [0, 0]], [Path.MOVETO, Path.CLOSEPOLY])

but instead returns

Path([[0,0]], [Path.CLOSEPOLY])

I'll push a fix shortly!

Edit: phrasing

@brunobeltran
Copy link
Contributor

I will note that while #17982 "fixes" the underlying bug, it does not revert to the same behavior as 3.2.

The new behavior is

>>> from matplotlib.patches import Polygon                                                                                                            
>>> pp = Polygon([[0.,0.]])                                                                                                                             
>>> pp.get_extents()  
Bbox([[0.0, 0.0], [0.0, 0.0]])

which seems more correct to me.

Sure, a degenerate polygon has zero width (ax.add_patch(PathPatch(Path([[0,0], [0, 0]], [Path.MOVETO, Path.CLOSEPOLY]))) renders nothing), but it does have well-defined extents. It just so happens that pp.get_extents().x0 == pp.get_extents().x1.

If we have users that are relying on Matplotlib to not include a bunch of degenerate Polygon patches far outside their plot bounds into the plot extents, then this will break their plots. However, since this behavior relied on a bug to work in the first place, I personally am okay with this change.

@QuLogic
Copy link
Member

QuLogic commented Jul 20, 2020

Maybe we consider that part of 'Fixed bug that computed a Path's Bbox incorrectly'.

@brunobeltran
Copy link
Contributor

Maybe we consider that part of 'Fixed bug that computed a Path's Bbox incorrectly'.

I agree with this, just wanted to make sure it didn't sneak past without someone else seeing the difference in case I was way off base.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants