1

I am trying to modify the plot shown in this answer, but replacing the fill_between with violin plots at each tick.

A naive implementation made me try following,

import matplotlib.pylab as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np

x   = np.linspace(1,5,100)
y1  = np.ones(x.size)
y2  = np.ones(x.size)*2
y3  = np.ones(x.size)*3
z   = np.sin(x/2)

plt.figure()
ax = plt.subplot(projection='3d')
ax.plot(x, y1, z, color='r')
ax.plot(x, y2, z, color='g')
ax.plot(x, y3, z, color='b')
handle = plt.violinplot(x)
ax.add_collection3d(handle, zs=1, zdir='y')

The error that pops up is: AttributeError: 'PolyCollection' object has no attribute 'do_3d_projection'.

The error origin can be traced by the following log:

  runcell(7, 'Figure.py')
Traceback (most recent call last):

  File "Figure.py", line 163, in <module>
    ax.add_collection3d(handle, zs=1, zdir='y')

  File "C:\Users\sarth\.conda\envs\master\lib\site-packages\mpl_toolkits\mplot3d\axes3d.py", line 2252, in add_collection3d
    super().add_collection(col)

  File "C:\Users\sarth\.conda\envs\master\lib\site-packages\matplotlib\axes\_base.py", line 1921, in add_collection
    label = collection.get_label()

AttributeError: 'dict' object has no attribute 'get_label'

Traceback (most recent call last):

  File "C:\Users\sarth\AppData\Roaming\Python\Python36\site-packages\IPython\core\formatters.py", line 341, in __call__
    return printer(obj)

  File "C:\Users\sarth\AppData\Roaming\Python\Python36\site-packages\IPython\core\pylabtools.py", line 248, in <lambda>
    png_formatter.for_type(Figure, lambda fig: print_figure(fig, 'png', **kwargs))

  File "C:\Users\sarth\AppData\Roaming\Python\Python36\site-packages\IPython\core\pylabtools.py", line 132, in print_figure
    fig.canvas.print_figure(bytes_io, **kw)

  File "C:\Users\sarth\.conda\envs\master\lib\site-packages\matplotlib\backend_bases.py", line 2193, in print_figure
    self.figure.draw(renderer)

  File "C:\Users\sarth\.conda\envs\master\lib\site-packages\matplotlib\artist.py", line 41, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)

  File "C:\Users\sarth\.conda\envs\master\lib\site-packages\matplotlib\figure.py", line 1864, in draw
    renderer, self, artists, self.suppressComposite)

  File "C:\Users\sarth\.conda\envs\master\lib\site-packages\matplotlib\image.py", line 131, in _draw_list_compositing_images
    a.draw(renderer)

  File "C:\Users\sarth\.conda\envs\master\lib\site-packages\matplotlib\artist.py", line 41, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)

  File "C:\Users\sarth\.conda\envs\master\lib\site-packages\mpl_toolkits\mplot3d\axes3d.py", line 447, in draw
    reverse=True)):

  File "C:\Users\sarth\.conda\envs\master\lib\site-packages\mpl_toolkits\mplot3d\axes3d.py", line 446, in <lambda>
    key=lambda col: col.do_3d_projection(renderer),

AttributeError: 'PolyCollection' object has no attribute 'do_3d_projection'

<Figure size 432x288 with 1 Axes>

Also tried using individual body objects using plt.violinplot(x)['objects'][i] but the same error is returned.

  • Did you try to add your [`violin-plot`](https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.violinplot.html) to a [`Poly3DCollection`](https://stackoverflow.com/questions/64029288/plotting-poly3dcollection-using-add-collection3d) before. And then add this using `add_collection3d` ? – hc_dev Aug 13 '21 at 08:01
  • From your code sample I can not spot the error-origin or call of `do_3d_projection`. Can you [edit] and post the __complete stacktrace__, please. – hc_dev Aug 13 '21 at 08:03
  • @hc_dev Tried but the error persists. – Sarth Dubey Aug 13 '21 at 08:14
  • I edited to include the error-origin log. – Sarth Dubey Aug 13 '21 at 08:16

0 Answers0