mpl_toolkits/mplot3d/axes3d.py in do_3d_projection(artist)
469 # avoid passing it to them; call this directly once the
470 # deprecation has expired.
--> 471 return artist.do_3d_projection()
472
473 _api.warn_deprecated(
matplotlib/_api/deprecation.py in wrapper(*inner_args, **inner_kwargs)
429 else deprecation_addendum,
430 **kwargs)
--> 431 return func(*inner_args, **inner_kwargs)
432
433 return wrapper
mpl_toolkits/mplot3d/art3d.py in do_3d_projection(self, renderer)
615
616 if len(self._linewidths3d) > 1:
--> 617 self._linewidths = self._linewidths3d[z_markers_idx]
618
619 # Re-order items
TypeError: only integer scalar arrays can be converted to a scalar index
This is because the type of self._sizes3d is numpy.ndarray, but type of self._linewidths3d is list.
Expected outcome
Array-like linewidth works for 3d plots as it does for 2d plots.
Additional information
ax.scatter(x, x, x, marker='o', s=x) works fine.
linewidths is a list regardless of user input type.
I don't know where linewidths gets converted to a list, but a quick fix is as simple as wrapping it in np.array call: self._linewidths = np.array(self._linewidths3d)[z_markers_idx] (tested that this fixes the issue).
Operating system
No response
Matplotlib Version
3.5.2 but also happens with older versions (3.3.x)
The safest solution would be to cast to numpy array in do_3d_projection, but it feels like _bcast_lwls should return a numpy array in first place (though such a change could break something elsewhere if there are other parts of the codebase expecting it to be a list). Any preferences?
Activity
krassowski commented on Jul 16, 2022
The conversion to list happens in parent class' (PathCollection) set_linewidth:
matplotlib/lib/matplotlib/collections.py
Lines 566 to 583 in 386d615
which gets called via super():
matplotlib/lib/mpl_toolkits/mplot3d/art3d.py
Lines 563 to 566 in 0d433b4
More specifically, the call to self._bcast_lwls leads to the linewidth getting converted to a list here:
matplotlib/lib/matplotlib/collections.py
Line 691 in 386d615
The safest solution would be to cast to numpy array in do_3d_projection, but it feels like _bcast_lwls should return a numpy array in first place (though such a change could break something elsewhere if there are other parts of the codebase expecting it to be a list). Any preferences?