Skip to content

mplot3d: add_collection3d issues #17755

@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

      pFad - Phonifier reborn

      Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

      Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


      Alternative Proxies:

      Alternative Proxy

      pFad Proxy

      pFad v3 Proxy

      pFad v4 Proxy