Matplotlib - Drawing a Trapezoid Isosceles with Poly3DCollection

Dear colleagues,
Exploring the 3D support for plotting
a simple trapezoid isosceles based on eight locations with x,y,z (imagine
a water tank). When doing a manual selection of the collections that defines
each surface plane, the drawing works well (see a sample below). Watching
for a more automated process that could work with a complex surface based
on any Polygons.
My question: Is there an algorithm,
or function in Numpy or Matplotlib that identifies the quartet of each
plane in the sample below? I’ve tried to apply Numpy function “combinations”,
but it generates too many collections.
Thanks in advance for your hint to optimize
this drawing with the Matplotlib with Poly3DCollection
Sample Code
-----------
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
from mpl_toolkits.mplot3d.art3d import Line3DCollection
import matplotlib.pyplot as plt
from matplotlib import cm
import matplotlib.colors as colors
from numpy import random
fig = plt.figure()
ax = Axes3D(fig)
# for random color settings
color = colors.rgb2hex(random.rand(3))
# blue color
color = 'b'
#mypoly = [[2, 0, -1], [2, 0, 1], [4, 0, 1], [4, 0, -1], [0, 4, -2], [0, 4, 2], [6, 4, 2], [6, 4, -2]]
# A B C D E F G H
# Colections for drawing 3D plot with polygon (each plane defined separately)
#plane#plane
b: A,E,F,B#plane
c: B,F,G,C#plane
d: C,G,H,D #plane
e: E,F,G,H#plane
f: A,B,C,D #plane
collection xa = [2,0,6,4] ya = [0,4,4,0]za = [-1,-2,-2,-1]#second collectionxb = [2,0,0,2] yb = [0,4,4,0]zb = [-1,-2,2,1]#third collectionxc = [2,0,6,4] yc = [0,4,4,0]zc = [1,2,2,1]#fourth collectionxd = [4,6,6,4] yd = [0,4,4,0]zd = [1,2,-2,-1]#fifth collection (kept open, to watch the plot result)xe = [0,0,6,6] ye = [4,4,4,4]ze = [-2,2,2,-2]#sixth collection xf = [2,2,4,4] yf = [0,0,0,0]zf = [-1,1,1,-1]# to doverts = [zip(xa, ya,za),zip(xb, yb,zb),zip(xc, yc,zc),zip(xd,
yd,zd),zip(xf, yf,zf)]ax.add_collection3d(Poly3DCollection(verts, facecolors=color,
linewidths=1, alpha=0.5))ax.add_collection3d(Line3DCollection(verts, colors=‘k’,
linewidths=0.2, linestyles=’:’))# set axis view# add gridax.grid(True)# viewax.set_xlim(-1,6)ax.set_ylim(-1,6)ax.set_zlim(-5,5)ax.view_init(elev=10., azim=110.)ax.get_xaxis().set_visible(True)ax.get_yaxis().set_visible(True)ax.set_autoscale_on(True)plt.show()`
Thanks for support.
Regards,
Claude

···

a: A,E,H,D`
**
Claude Falbriard
Certified IT Specialist L2 - Middleware
AMS Hortolândia / SP - Brazil
phone: +55 13 9 9760 0453
cell: +55 13 9 8117 3316
e-mail: claudef@…3779…**

Not that I am aware of. We kind of brute-force it in the plot_surface() function:

    polys = []
    # Only need these vectors to shade if there is no cmap
    if cmap is None and shade :

        totpts = int(np.ceil(float(rows - 1) / rstride) *
                     np.ceil(float(cols - 1) / cstride))
        v1 = np.empty((totpts, 3))
        v2 = np.empty((totpts, 3))
        # This indexes the vertex points

        which_pt = 0

    #colset contains the data for coloring: either average z or the facecolor
    colset = []
    for rs in xrange(0, rows-1, rstride):
        for cs in xrange(0, cols-1, cstride):

            ps = []
            for a in (X, Y, Z) :
                ztop = a[rs,cs:min(cols, cs+cstride+1)]
                zleft = a[rs+1:min(rows, rs+rstride+1),
                          min(cols-1, cs+cstride)]

                zbase = a[min(rows-1, rs+rstride), cs:min(cols, cs+cstride+1):][::-1]
                zright = a[rs:min(rows-1, rs+rstride):, cs][::-1]
                z = np.concatenate((ztop, zleft, zbase, zright))

                ps.append(z)

            # The construction leaves the array with duplicate points, which
            # are removed here.
            ps = zip(*ps)
            lastp = np.array([])

            ps2 = [ps[0]] + [ps[i] for i in xrange(1, len(ps)) if ps[i] != ps[i-1]]
            avgzsum = sum(p[2] for p in ps2)
            polys.append(ps2)

            if fcolors is not None:

                colset.append(fcolors[rs][cs])
            else:
                colset.append(avgzsum / len(ps2))

            # Only need vectors to shade if no cmap
            if cmap is None and shade:

                i1, i2, i3 = 0, int(len(ps2)/3), int(2*len(ps2)/3)
                v1[which_pt] = np.array(ps2[i1]) - np.array(ps2[i2])
                v2[which_pt] = np.array(ps2[i2]) - np.array(ps2[i3])

                which_pt += 1
    if cmap is None and shade:
        normals = np.cross(v1, v2)
    else :
        normals = []

If you find a better way to do this, I will owe you some beers.

Cheers!

Ben Root

···

On Wed, Mar 26, 2014 at 7:17 AM, <claudef@…3779…> wrote:

Dear colleagues,
Exploring the 3D support for plotting
a simple trapezoid isosceles based on eight locations with x,y,z (imagine
a water tank). When doing a manual selection of the collections that defines
each surface plane, the drawing works well (see a sample below). Watching
for a more automated process that could work with a complex surface based
on any Polygons.
My question: Is there an algorithm,
or function in Numpy or Matplotlib that identifies the quartet of each
plane in the sample below? I’ve tried to apply Numpy function “combinations”,
but it generates too many collections.
Thanks in advance for your hint to optimize
this drawing with the Matplotlib with Poly3DCollection
Sample Code
-----------
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
from mpl_toolkits.mplot3d.art3d import Line3DCollection
import matplotlib.pyplot as plt
from matplotlib import cm
import matplotlib.colors as colors
from numpy import random
fig = plt.figure()
ax = Axes3D(fig)
# for random color settings
color = colors.rgb2hex(random.rand(3))
# blue color
color = 'b'
#mypoly = [[2, 0, -1], [2, 0, 1], [4, 0, 1], [4, 0, -1], [0, 4, -2], [0, 4, 2], [6, 4, 2], [6, 4, -2]]
# A B C D E F G H
# Colections for drawing 3D plot with polygon (each plane defined separately)
#planea: A,E,H,D
#planeb: A,E,F,B
#planec: B,F,G,C
#planed: C,G,H,D
#planee: E,F,G,H
#planef: A,B,C,D
#planecollection
xa = [2,0,6,4]
ya = [0,4,4,0]
za = [-1,-2,-2,-1]
#second collection
xb = [2,0,0,2]
yb = [0,4,4,0]
zb = [-1,-2,2,1]
#third collection
xc = [2,0,6,4]
yc = [0,4,4,0]
zc = [1,2,2,1]
#fourth collection
xd = [4,6,6,4]
yd = [0,4,4,0]
zd = [1,2,-2,-1]
#fifth collection (kept open, to watch the plot result)
xe = [0,0,6,6]
ye = [4,4,4,4]
ze = [-2,2,2,-2]
#sixth collection
xf = [2,2,4,4]
yf = [0,0,0,0]
zf = [-1,1,1,-1]
# to do
verts = [zip(xa, ya,za),zip(xb, yb,zb),zip(xc, yc,zc),zip(xd, yd,zd),zip(xf, yf,zf)]
ax.add_collection3d(Poly3DCollection(verts, facecolors=color, linewidths=1, alpha=0.5))
ax.add_collection3d(Line3DCollection(verts, colors='k', linewidths=0.2, linestyles=':'))
# set axis view
# add grid
ax.grid(True)
# view
ax.set_xlim(-1,6)
ax.set_ylim(-1,6)
ax.set_zlim(-5,5)
ax.view_init(elev=10., azim=110.)
ax.get_xaxis().set_visible(True)
ax.get_yaxis().set_visible(True)
ax.set_autoscale_on(True)
plt.show()
Thanks for support.
Regards,
Claude
**
Claude Falbriard
Certified IT Specialist L2 - Middleware
AMS Hortolândia / SP - Brazil
phone: +55 13 9 9760 0453
cell: +55 13 9 8117 3316
e-mail: claudef@…3779…**

Learn Graph Databases - Download FREE O’Reilly Book

“Graph Databases” is the definitive new guide to graph databases and their

applications. Written by three acclaimed leaders in the field,

this first edition is now available. Download your free book today!

http://p.sf.net/sfu/13534_NeoTech


Matplotlib-users mailing list

Matplotlib-users@lists.sourceforge.net

https://lists.sourceforge.net/lists/listinfo/matplotlib-users