Skip to content

mplot3d: add_collection3d issues #17755

Closed
@thangleiter

Description

@thangleiter

Bug report

Bug summary

  1. When plotting a parametrized line in 3D using LineCollection, a ValueError is thrown when Axes3D.add_collection_3d upconverts 2D Collections with the zs parameter.
    In the MWE below, this is because this line in _paths_to_3d_segments tries to broadcast a 2D array (number of line segments on the first axis and segment start & end on the second) to a 1D array (number of line segments):
    zs = np.broadcast_to(zs, len(paths))

    Commenting out this line will make the example work.
  2. Additionally, add_collection3d does not return the collection like add_collection does (it does not return anything). Hence, you cannot pass the collection object to, e.g., a colorbar call:
    elif type(col) is mcoll.PatchCollection:
    art3d.patch_collection_2d_to_3d(col, zs=zs, zdir=zdir)
    col.set_sort_zpos(zsortval)
    super().add_collection(col)
    def scatter(self, xs, ys, zs=0, zdir='z', s=20, c=None, depthshade=True,

    Simply returning the return value of the call to super().add_collection does the trick for me here:
collection = super().add_collection(col)
return collection

Code for reproduction

A minimal working example (including the reason why I use LineCollection instead of plot, namely a multicolored line) stitched together from two official examples (1, 2) is:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection

theta = np.linspace(-4 * np.pi, 4 * np.pi, 100)
z = np.linspace(-2, 2, 100)
r = z**2 + 1
x = r * np.sin(theta)
y = r * np.cos(theta)

points = np.array([x, y, z]).T.reshape(-1, 1, 3)
segments = np.concatenate([points[:-1], points[1:]], axis=1)

fig = plt.figure()
ax = fig.gca(projection='3d')

norm = plt.Normalize(0, 2*np.pi)
# 2D LineCollection from x & y values
lc = LineCollection(segments[:, :, :2], cmap='twilight', norm=norm)
lc.set_array(np.mod(theta, 2*np.pi))
# Add 2D collection at z values to ax
line = ax.add_collection3d(lc, zs=segments[:, :, 2])  # line is None

# fig.colorbar(line, ax=ax)  # Would fail because add_collection3d does not return the collection

ax.set_xlim(-5, 5)
ax.set_ylim(-4, 6)
ax.set_zlim(-2, 2)
plt.show()

Actual outcome

Traceback (most recent call last):

  File "<ipython-input-1-d8492282873b>", line 23, in <module>
    line = ax.add_collection3d(lc, zs=segments[:, :, 2])

  File "c:\users\hangleiter\appdata\local\continuum\anaconda3\envs\py38\lib\site-packages\mpl_toolkits\mplot3d\axes3d.py", line 2178, in add_collection3d
    art3d.line_collection_2d_to_3d(col, zs=zs, zdir=zdir)

  File "c:\users\hangleiter\appdata\local\continuum\anaconda3\envs\py38\lib\site-packages\mpl_toolkits\mplot3d\art3d.py", line 332, in line_collection_2d_to_3d
    segments3d = _paths_to_3d_segments(col.get_paths(), zs, zdir)

  File "c:\users\hangleiter\appdata\local\continuum\anaconda3\envs\py38\lib\site-packages\mpl_toolkits\mplot3d\art3d.py", line 234, in _paths_to_3d_segments
    zs = np.broadcast_to(zs, len(paths))

  File "<__array_function__ internals>", line 5, in broadcast_to

  File "C:\Users\hangleiter\AppData\Local\Continuum\anaconda3\envs\py38\lib\site-packages\numpy\lib\stride_tricks.py", line 182, in broadcast_to
    return _broadcast_to(array, shape, subok=subok, readonly=True)

  File "C:\Users\hangleiter\AppData\Local\Continuum\anaconda3\envs\py38\lib\site-packages\numpy\lib\stride_tricks.py", line 125, in _broadcast_to
    it = np.nditer(

ValueError: input operand has more dimensions than allowed by the axis remapping

Expected outcome
This is the result if both of the above fixes are applied:
grafik

Matplotlib version

  • Operating system: Windows
  • Matplotlib version: 3.2.2
  • Matplotlib backend (print(matplotlib.get_backend())): module://ipykernel.pylab.backend_inline
  • Python version: 3.8.3
  • Numpy version: 1.18.5

Matplotlib is installed via conda:defaults.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions