[Bug]: Poly3DCollection initialization cannot properly handle parameter verts when it is a list of nested tuples and shade is False · Issue #29156 · matplotlib/matplotlib · GitHub | Latest TMZ Celebrity News & Gossip | Watch TMZ Live
Skip to content

[Bug]: Poly3DCollection initialization cannot properly handle parameter verts when it is a list of nested tuples and shade is False  #29156

Closed
@williamlus

Description

@williamlus

Bug summary

The initialization of an mpl_toolkits.mplot3d.Poly3DCollection object cannot properly handle the parameter verts when verts = a list of (N, 3) array-like nested tuples, and shade=False.

Code for reproduction

from mpl_toolkits.mplot3d import art3d
corners = ((0, 0, 0), (0, 5, 0), (5, 5, 0), (5, 0, 0))
tri = art3d.Poly3DCollection([corners], shade=True) # Failed when shade=True
# tri = art3d.Poly3DCollection([corners]) # Passed with the default setting shade=False

Actual outcome


TypeError Traceback (most recent call last)
Cell In[3], line 1
----> 1 tri = art3d.Poly3DCollection([corners], shade=True)

File ~/anaconda3/envs/testmpl/lib/python3.12/site-packages/mpl_toolkits/mplot3d/art3d.py:905, in Poly3DCollection.init(self, verts, zsort, shade, lightsource, *args, **kwargs)
875 """
876 Parameters
877 ----------
(...)
902 and _edgecolors properties.
903 """
904 if shade:
--> 905 normals = _generate_normals(verts)
906 facecolors = kwargs.get('facecolors', None)
907 if facecolors is not None:

File ~/anaconda3/envs/testmpl/lib/python3.12/site-packages/mpl_toolkits/mplot3d/art3d.py:1222, in _generate_normals(polygons)
1220 n = len(ps)
1221 i1, i2, i3 = 0, n//3, 2*n//3
-> 1222 v1[poly_i, :] = ps[i1, :] - ps[i2, :]
1223 v2[poly_i, :] = ps[i2, :] - ps[i3, :]
1224 return np.cross(v1, v2)

TypeError: tuple indices must be integers or slices, not tuple

Expected outcome

No error.

Additional information

When shade=True, the __init__ function will first call the function _generate_normals(polygons), where polygons=verts. In our case, verts is not an instance of np.ndarray but a list, so it enters the for loop:

        for poly_i, ps in enumerate(polygons):
            n = len(ps)
            i1, i2, i3 = 0, n//3, 2*n//3
            v1[poly_i, :] = ps[i1, :] - ps[i2, :]
            v2[poly_i, :] = ps[i2, :] - ps[i3, :]

polygons is [((0, 0, 0), (0, 5, 0), (5, 5, 0), (5, 0, 0))], and ps is a nested tuple, so we need to convert ps to np.ndarray before using the array slicing like ps[i1, :]. A possible fix may be setting ps = np.asarray(ps) before array slicing.

Operating system

No response

Matplotlib Version

3.9.2

Matplotlib Backend

No response

Python version

No response

Jupyter version

No response

Installation

None

Metadata

Metadata

Assignees

No one assigned

    Labels

    Difficulty: Easyhttps://matplotlib.org/devdocs/devel/contribute.html#good-first-issuesGood first issueOpen a pull request against these issues if there are no active ones!topic: mplot3d

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      TMZ Celebrity News – Breaking Stories, Videos & Gossip

      Looking for the latest TMZ celebrity news? You've come to the right place. From shocking Hollywood scandals to exclusive videos, TMZ delivers it all in real time.

      Whether it’s a red carpet slip-up, a viral paparazzi moment, or a legal drama involving your favorite stars, TMZ news is always first to break the story. Stay in the loop with daily updates, insider tips, and jaw-dropping photos.

      🎥 Watch TMZ Live

      TMZ Live brings you daily celebrity news and interviews straight from the TMZ newsroom. Don’t miss a beat—watch now and see what’s trending in Hollywood.