Plotting 3D Polygons in Python 3
Question: In my quest to somehow get 3D polygons to actually plot, I came across the
following script (EDIT: modified slightly): [Plotting 3D Polygons in python-
matplotlib](http://stackoverflow.com/questions/4622057/plotting-3d-polygons-
in-python-matplotlib)

    
    
    from mpl_toolkits.mplot3d import Axes3D
    from matplotlib.collections import Poly3DCollection
    import matplotlib.pyplot as plt
    fig = plt.figure()
    ax = Axes3D(fig)
    x = [0,1,1,0]
    y = [0,0,1,1]
    z = [0,1,0,1]
    verts = [zip(x, y,z)]
    ax.add_collection3d(Poly3DCollection(verts),zs=z)
    plt.show()
    

But when I run that, I get the following error message:

    
    
    TypeError: object of type 'zip' has no len()
    

It seems that this may be a Python 2 vs. 3 thing, as I am running in Python 3,
and that post is five years old. So I changed the third-to-last line to:

    
    
    verts = list(zip(x, y, z))
    

Now verts shows up in the variable list, but I still get an error:

    
    
    TypeError: zip argument #1 must support iteration
    

What? How do I fix this?


Answer: I've had a similar problem with the zipping. I support the thesis it is a
python 2.x vs 3.x thing.

However, I've found somewhere that apparently works:

    
    
    from mpl_toolkits.mplot3d import Axes3D
    from mpl_toolkits.mplot3d.art3d import Poly3DCollection
    import matplotlib.pyplot as plt
    
    fig = plt.figure()
    ax = Axes3D(fig)
    x = [0, 1, 1, 0]
    y = [0, 0, 1, 1]
    z = [0, 1, 0, 1]
    verts = [list(zip(x, y, z))]
    print(verts)
    ax.add_collection3d(Poly3DCollection(verts), zs='z')
    plt.show()
    

I've thus made two changes:

  1. replaced the line: `from matplotlib.collections import Poly3DCollection` by: `from matplotlib.mplot3.art3d import Poly3DCollection`.

I don't know where your import statement originates from, but it didn't seem
to work for me

  2. changed the line: `verts = list(zip(x,y,z))` to `verts = [list(zip(x, y, z))]`

Somehow, the latter seems to work. Having just started myself with python, I
cannot offer an iron-clad explanation. However, here goes nothing: the class
Poly3DCollection requires as the first input parameter a "collection", hence a
list of lists. In this case, only list is given, which is assumed thus missed
a level. By adding another level to it (via the [...]) it worked.

I've got no idea if this explanation makes sense, however it fits intuitively
to me ;)

These modifications seem to work, as this code creates the desired 3D polygon
(I've noticed that since this is my first post, I'm not allowed to post a
proof-of-the-pudding figure.... )

hope this was useful,

kind regards

