Revision: 7265
          http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7265&view=rev
Author:   heeres
Date:     2009-07-17 07:24:06 +0000 (Fri, 17 Jul 2009)

Log Message:
-----------
mplot3d: add bar3d, improve z-sort, hist3d example

Modified Paths:
--------------
    trunk/matplotlib/lib/mpl_toolkits/mplot3d/art3d.py
    trunk/matplotlib/lib/mpl_toolkits/mplot3d/axes3d.py

Added Paths:
-----------
    trunk/matplotlib/examples/mplot3d/hist3d_demo.py

Added: trunk/matplotlib/examples/mplot3d/hist3d_demo.py
===================================================================
--- trunk/matplotlib/examples/mplot3d/hist3d_demo.py                            
(rev 0)
+++ trunk/matplotlib/examples/mplot3d/hist3d_demo.py    2009-07-17 07:24:06 UTC 
(rev 7265)
@@ -0,0 +1,27 @@
+from mpl_toolkits.mplot3d import Axes3D
+from matplotlib.collections import PolyCollection
+from matplotlib.colors import colorConverter
+import pylab
+import random
+import numpy as np
+
+fig = pylab.figure()
+ax = Axes3D(fig)
+x = np.random.rand(100) * 4
+y = np.random.rand(100) * 4
+hist, xedges, yedges = np.histogram2d(x, y, bins=4)
+
+elements = (len(xedges) - 1) * (len(yedges) - 1)
+xpos, ypos = np.meshgrid(
+        [xedges[i] + 0.25 for i in range(len(xedges) - 1)],
+        [yedges[i] + 0.25 for i in range(len(yedges) - 1)])
+xpos = xpos.flatten()
+ypos = ypos.flatten()
+zpos = [0] * elements
+dx = [0.5] * elements
+dy = [0.5] * elements
+dz = hist.flatten()
+ax.bar3d(xpos, ypos, zpos, dx, dy, dz, color='b')
+
+pylab.show()
+

Modified: trunk/matplotlib/lib/mpl_toolkits/mplot3d/art3d.py
===================================================================
--- trunk/matplotlib/lib/mpl_toolkits/mplot3d/art3d.py  2009-07-16 20:53:24 UTC 
(rev 7264)
+++ trunk/matplotlib/lib/mpl_toolkits/mplot3d/art3d.py  2009-07-17 07:24:06 UTC 
(rev 7265)
@@ -271,6 +271,7 @@
 
         PolyCollection.__init__(self, verts, *args, **kwargs)
         self._zsort = 1
+        self._sort_zpos = None
 
     def get_vector(self, segments3d):
         """Optimize points for projection"""
@@ -287,7 +288,6 @@
         ones = np.ones(len(xs))
         self._vec = np.array([xs, ys, zs, ones])
         self._segis = segis
-        self._sort_zpos = min(zs)
 
     def set_verts(self, verts, closed=True):
         '''Set 3D vertices.'''
@@ -297,9 +297,13 @@
 
     def set_3d_properties(self):
         self._zsort = 1
+        self._sort_zpos = None
         self._facecolors3d = PolyCollection.get_facecolors(self)
         self._edgecolors3d = PolyCollection.get_edgecolors(self)
 
+    def set_sort_zpos(self, val):
+        self._sort_zpos = val
+
     def do_3d_projection(self, renderer):
         '''
         Perform the 3D projection for this object.
@@ -315,17 +319,19 @@
 
         # This extra fuss is to re-order face / edge colors
         cface = self._facecolors3d
-        if len(self._edgecolors3d) != len(cface):
-            cedge = cface
-        else:
-            cedge = self._edgecolors3d
+        cedge = self._edgecolors3d
+        if len(cface) != len(xyzlist):
+            cface = cface.repeat(len(xyzlist), axis=0)
+        if len(cedge) != len(xyzlist):
+            if len(cedge) == 0:
+                cedge = cface
+            cedge = cedge.repeat(len(xyzlist), axis=0)
 
         # if required sort by depth (furthest drawn first)
         if self._zsort:
-            z_segments_2d = [(min(zs), zip(xs, ys), fc, ec) for
+            z_segments_2d = [(np.average(zs), zip(xs, ys), fc, ec) for
                     (xs, ys, zs), fc, ec in zip(xyzlist, cface, cedge)]
-            z_segments_2d.sort()
-            z_segments_2d.reverse()
+            z_segments_2d.sort(reverse=True)
         else:
             raise ValueError, "whoops"
 
@@ -339,9 +345,12 @@
             self._edgecolors2d = self._edgecolors3d
 
         # Return zorder value
-        zvec = np.array([[0], [0], [self._sort_zpos], [1]])
-        ztrans = proj3d.proj_transform_vec(zvec, renderer.M)
-        return ztrans[2][0]
+        if self._sort_zpos is not None:
+           zvec = np.array([[0], [0], [self._sort_zpos], [1]])
+           ztrans = proj3d.proj_transform_vec(zvec, renderer.M)
+           return ztrans[2][0]
+        else:
+            return np.min(tzs)
 
     def set_facecolor(self, colors):
         PolyCollection.set_facecolor(self, colors)

Modified: trunk/matplotlib/lib/mpl_toolkits/mplot3d/axes3d.py
===================================================================
--- trunk/matplotlib/lib/mpl_toolkits/mplot3d/axes3d.py 2009-07-16 20:53:24 UTC 
(rev 7264)
+++ trunk/matplotlib/lib/mpl_toolkits/mplot3d/axes3d.py 2009-07-17 07:24:06 UTC 
(rev 7265)
@@ -625,6 +625,20 @@
 
         return polyc
 
+    def _generate_normals(self, polygons):
+        '''
+        Generate normals for polygons by using the first three points.
+        This normal of course might not make sense for polygons with
+        more than three points not lying in a plane.
+        '''
+
+        normals = []
+        for verts in polygons:
+            v1 = np.array(verts[0]) - np.array(verts[1])
+            v2 = np.array(verts[2]) - np.array(verts[0])
+            normals.append(np.cross(v1, v2))
+        return normals
+
     def _shade_colors(self, color, normals):
         shade = []
         for n in normals:
@@ -733,6 +747,7 @@
             colors2 = self._shade_colors(color, normals)
             polycol = art3d.Poly3DCollection(polyverts, facecolors=colors,
                 edgecolors=colors2)
+            polycol.set_sort_zpos(z)
             self.add_collection3d(polycol)
 
         for col in colls:
@@ -792,6 +807,7 @@
         colls = cset.collections
         for z1, z2, linec in zip(levels, levels[1:], colls):
             art3d.poly_collection_2d_to_3d(linec, z1)
+            linec.set_sort_zpos(z1)
 
         self.auto_scale_xyz(X, Y, Z, had_data)
         return cset
@@ -813,10 +829,13 @@
 
         if type(col) is collections.PolyCollection:
             art3d.poly_collection_2d_to_3d(col, zs=zs, zdir=zdir)
+            col.set_sort_zpos(min(zs))
         elif type(col) is collections.LineCollection:
             art3d.line_collection_2d_to_3d(col, zs=zs, zdir=zdir)
+            col.set_sort_zpos(min(zs))
         elif type(col) is collections.PatchCollection:
             art3d.patch_collection_2d_to_3d(col, zs=zs, zdir=zdir)
+            col.set_sort_zpos(min(zs))
 
         Axes.add_collection(self, col)
 
@@ -902,6 +921,64 @@
 
         return patches
 
+    def bar3d(self, x, y, z, dx, dy, dz, color='b'):
+        '''
+        Generate a 3D bar, or multiple bars.
+
+        When generating multiple bars, x, y, z have to be arrays.
+        dx, dy, dz can still be scalars.
+        '''
+
+        had_data = self.has_data()
+
+        if not cbook.iterable(x):
+            print 'not interable'
+            x, y, z = [x], [y], [z]
+        if not cbook.iterable(dx):
+            dx, dy, dz = [dx], [dy], [dz]
+        if len(dx) == 1:
+            dx = dx * len(x)
+            dy = dy * len(x)
+            dz = dz * len(x)
+
+        minx, miny, minz = 1e20, 1e20, 1e20
+        maxx, maxy, maxz = -1e20, -1e20, -1e20
+
+        polys = []
+        for xi, yi, zi, dxi, dyi, dzi in zip(x, y, z, dx, dy, dz):
+            minx = min(xi, minx)
+            maxx = max(xi + dxi, maxx)
+            miny = min(yi, miny)
+            maxy = max(yi + dyi, maxy)
+            minz = min(zi, minz)
+            maxz = max(zi + dzi, maxz)
+
+            polys.extend([
+                ((xi, yi, zi), (xi + dxi, yi, zi),
+                    (xi + dxi, yi + dyi, zi), (xi, yi + dyi, zi)),
+                ((xi, yi, zi + dzi), (xi + dxi, yi, zi + dzi),
+                    (xi + dxi, yi + dyi, zi + dzi), (xi, yi + dyi, zi + dzi)),
+
+                ((xi, yi, zi), (xi + dxi, yi, zi),
+                    (xi + dxi, yi, zi + dzi), (xi, yi, zi + dzi)),
+                ((xi, yi + dyi, zi), (xi + dxi, yi + dyi, zi),
+                    (xi + dxi, yi + dyi, zi + dzi), (xi, yi + dyi, zi + dzi)),
+
+                ((xi, yi, zi), (xi, yi + dyi, zi),
+                    (xi, yi + dyi, zi + dzi), (xi, yi, zi + dzi)),
+                ((xi + dxi, yi, zi), (xi + dxi, yi + dyi, zi),
+                    (xi + dxi, yi + dyi, zi + dzi), (xi + dxi, yi, zi + dzi)),
+            ])
+
+        color = np.array(colorConverter.to_rgba(color))
+        normals = self._generate_normals(polys)
+        colors = self._shade_colors(color, normals)
+
+        col = art3d.Poly3DCollection(polys, facecolor=colors)
+        self.add_collection(col)
+
+        self.auto_scale_xyz((minx, maxx), (miny, maxy), (minz, maxz), had_data)
+
 def get_test_data(delta=0.05):
     '''
     Return a tuple X, Y, Z with a test data set.


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
Enter the BlackBerry Developer Challenge  
This is your chance to win up to $100,000 in prizes! For a limited time, 
vendors submitting new applications to BlackBerry App World(TM) will have
the opportunity to enter the BlackBerry Developer Challenge. See full prize  
details at: http://p.sf.net/sfu/Challenge
_______________________________________________
Matplotlib-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins

Reply via email to