Revision: 8199
          http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8199&view=rev
Author:   heeres
Date:     2010-03-19 17:12:41 +0000 (Fri, 19 Mar 2010)

Log Message:
-----------
Some fixes

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

Modified: trunk/matplotlib/examples/mplot3d/hist3d_demo.py
===================================================================
--- trunk/matplotlib/examples/mplot3d/hist3d_demo.py    2010-03-19 16:50:37 UTC 
(rev 8198)
+++ trunk/matplotlib/examples/mplot3d/hist3d_demo.py    2010-03-19 17:12:41 UTC 
(rev 8199)
@@ -17,7 +17,7 @@
 dy = dx.copy()
 dz = hist.flatten()
 
-ax.bar3d(xpos, ypos, zpos, dx, dy, dz, color='b')
+ax.bar3d(xpos, ypos, zpos, dx, dy, dz, color='b', zsort='average')
 
 plt.show()
 

Modified: trunk/matplotlib/examples/mplot3d/text3d_demo.py
===================================================================
--- trunk/matplotlib/examples/mplot3d/text3d_demo.py    2010-03-19 16:50:37 UTC 
(rev 8198)
+++ trunk/matplotlib/examples/mplot3d/text3d_demo.py    2010-03-19 17:12:41 UTC 
(rev 8199)
@@ -13,6 +13,9 @@
     label = '(%d, %d, %d), dir=%s' % (x, y, z, zdir)
     ax.text(x, y, z, label, zdir)
 
+ax.text(1, 1, 1, "red", color='red')
+ax.text2D(0.05, 0.95, "2D Text", transform=ax.transAxes)
+
 ax.set_xlim3d(0, 10)
 ax.set_ylim3d(0, 10)
 ax.set_zlim3d(0, 10)

Modified: trunk/matplotlib/lib/mpl_toolkits/mplot3d/art3d.py
===================================================================
--- trunk/matplotlib/lib/mpl_toolkits/mplot3d/art3d.py  2010-03-19 16:50:37 UTC 
(rev 8198)
+++ trunk/matplotlib/lib/mpl_toolkits/mplot3d/art3d.py  2010-03-19 17:12:41 UTC 
(rev 8199)
@@ -1,6 +1,7 @@
 #!/usr/bin/python
 # art3d.py, original mplot3d version by John Porter
 # Parts rewritten by Reinier Heeres <rein...@heeres.eu>
+# Minor additions by Ben Axelrod <baxel...@coroware.com>
 
 '''
 Module containing 3D artist code and functions to convert 2D
@@ -15,6 +16,7 @@
 from matplotlib.colors import Normalize
 from matplotlib.cbook import iterable
 
+import warnings
 import numpy as np
 import math
 import proj3d
@@ -52,8 +54,15 @@
     Text object with 3D position and (in the future) direction.
     '''
 
-    def __init__(self, x=0, y=0, z=0, text='', zdir='z'):
-        mtext.Text.__init__(self, x, y, text)
+    def __init__(self, x=0, y=0, z=0, text='', zdir='z', **kwargs):
+        '''
+        *x*, *y*, *z*  Position of text
+        *text*         Text string to display
+        *zdir*         Direction of text
+
+        Keyword arguments are passed onto :func:`~matplotlib.text.Text`.
+        '''
+        mtext.Text.__init__(self, x, y, text, **kwargs)
         self.set_3d_properties(z, zdir)
 
     def set_3d_properties(self, z=0, zdir='z'):
@@ -86,6 +95,9 @@
     '''
 
     def __init__(self, xs, ys, zs, *args, **kwargs):
+        '''
+        Keyword arguments are passed onto :func:`~matplotlib.lines.Line2D`.
+        '''
         lines.Line2D.__init__(self, [], [], *args, **kwargs)
         self._verts3d = xs, ys, zs
 
@@ -145,6 +157,9 @@
     '''
 
     def __init__(self, segments, *args, **kwargs):
+        '''
+        Keyword arguments are passed onto 
:func:`~matplotlib.collections.LineCollection`.
+        '''
         LineCollection.__init__(self, segments, *args, **kwargs)
 
     def set_segments(self, segments):
@@ -317,13 +332,44 @@
 
         *verts* should contain 3D coordinates.
 
+        Keyword arguments:
+        zsort, see set_zsort for options.
+
         Note that this class does a bit of magic with the _facecolors
         and _edgecolors properties.
         '''
 
+        self.set_zsort(kwargs.pop('zsort', True))
+
         PolyCollection.__init__(self, verts, *args, **kwargs)
-        self._zsort = 1
+
+    _zsort_functions = {
+        'average': np.average,
+        'min': np.min,
+        'max': np.max,
+    }
+
+    def set_zsort(self, zsort):
+        '''
+        Set z-sorting behaviour:
+            boolean: if True use default 'average'
+            string: 'average', 'min' or 'max'
+        '''
+
+        if zsort is True:
+            zsort = 'average'
+
+        if zsort is not False:
+            if zsort in self._zsort_functions:
+                zsortfunc = self._zsort_functions[zsort]
+            else:
+                return False
+        else:
+            zsortfunc = None
+
+        self._zsort = zsort
         self._sort_zpos = None
+        self._zsortfunc = zsortfunc
 
     def get_vector(self, segments3d):
         """Optimize points for projection"""
@@ -348,12 +394,13 @@
         PolyCollection.set_verts(self, [], closed)
 
     def set_3d_properties(self):
-        self._zsort = 1
         self._sort_zpos = None
+        self.set_zsort(True)
         self._facecolors3d = PolyCollection.get_facecolors(self)
         self._edgecolors3d = PolyCollection.get_edgecolors(self)
 
-    def set_sort_zpos(self, val):
+    def set_sort_zpos(self,val):
+        '''Set the position to use for z-sorting.'''
         self._sort_zpos = val
 
     def do_3d_projection(self, renderer):
@@ -381,7 +428,7 @@
 
         # if required sort by depth (furthest drawn first)
         if self._zsort:
-            z_segments_2d = [(np.average(zs), zip(xs, ys), fc, ec) for
+            z_segments_2d = [(self._zsortfunc(zs), zip(xs, ys), fc, ec) for
                     (xs, ys, zs), fc, ec in zip(xyzlist, cface, cedge)]
             z_segments_2d.sort(cmp=lambda x, y: cmp(y[0], x[0]))
         else:
@@ -468,9 +515,14 @@
 
 def iscolor(c):
     try:
-        return (len(c) == 4 or len(c) == 3) and hasattr(c[0], '__float__')
-    except (IndexError):
+        if len(c) == 4 or len(c) == 3:
+            if iterable(c[0]):
+                return False
+            if hasattr(c[0], '__float__'):
+                return True
+    except:
         return False
+    return False
 
 def get_colors(c, num):
     """Stretch the color argument to provide the required number num"""
@@ -484,6 +536,8 @@
         return c
     elif iscolor(c):
         return [c] * num
+    elif len(c) == 0: #if edgecolor or facecolor is specified as 'none'
+        return [[0,0,0,0]] * num
     elif iscolor(c[0]):
         return [c[0]] * num
     else:

Modified: trunk/matplotlib/lib/mpl_toolkits/mplot3d/axes3d.py
===================================================================
--- trunk/matplotlib/lib/mpl_toolkits/mplot3d/axes3d.py 2010-03-19 16:50:37 UTC 
(rev 8198)
+++ trunk/matplotlib/lib/mpl_toolkits/mplot3d/axes3d.py 2010-03-19 17:12:41 UTC 
(rev 8199)
@@ -2,12 +2,14 @@
 # axes3d.py, original mplot3d version by John Porter
 # Created: 23 Sep 2005
 # Parts fixed by Reinier Heeres <rein...@heeres.eu>
+# Minor additions by Ben Axelrod <baxel...@coroware.com>
 
 """
 Module containing Axes3D, an object which can plot 3D objects on a
 2D matplotlib figure.
 """
 
+import warnings
 from matplotlib.axes import Axes, rcParams
 from matplotlib import cbook
 from matplotlib.transforms import Bbox
@@ -55,7 +57,7 @@
         if rect is None:
             rect = [0.0, 0.0, 1.0, 1.0]
         self.fig = fig
-        self.cids = []
+        self._cids = []
 
         azim = kwargs.pop('azim', -60)
         elev = kwargs.pop('elev', 30)
@@ -147,7 +149,7 @@
 
         # Calculate projection of collections and zorder them
         zlist = [(col.do_3d_projection(renderer), col) \
-                for col in self.collections]
+                 for col in self.collections]
         zlist.sort()
         zlist.reverse()
         for i, (z, col) in enumerate(zlist):
@@ -322,23 +324,52 @@
         M = np.dot(perspM, M0)
         return M
 
-    def mouse_init(self):
+    def mouse_init(self, rotate_btn=1, zoom_btn=3):
+        """Initializes mouse button callbacks to enable 3D rotation of
+        the axes.  Also optionally sets the mouse buttons for 3D rotation
+        and zooming.
+
+        ============  ================================================
+        Argument      Description
+        ============  ================================================
+        *rotate_btn*  The integer or list of integers specifying which mouse
+                      button or buttons to use for 3D rotation of the axes.
+                      Default = 1.
+
+        *zoom_btn*    The integer or list of integers specifying which mouse
+                      button or buttons to use to zoom the 3D axes.
+                      Default = 3.
+        ============  ================================================
+        """
         self.button_pressed = None
         canv = self.figure.canvas
         if canv != None:
             c1 = canv.mpl_connect('motion_notify_event', self._on_move)
             c2 = canv.mpl_connect('button_press_event', self._button_press)
             c3 = canv.mpl_connect('button_release_event', self._button_release)
-            self.cids = [c1, c2, c3]
+            self._cids = [c1, c2, c3]
+        else:
+            warnings.warn('Axes3D.figure.canvas is \'None\', mouse rotation 
disabled.  Set canvas then call Axes3D.mouse_init().')
 
+        self._rotate_btn = np.atleast_1d(rotate_btn)
+        self._zoom_btn = np.atleast_1d(zoom_btn)
+
     def cla(self):
-        # Disconnect the various events we set.
-        for cid in self.cids:
-            self.figure.canvas.mpl_disconnect(cid)
-        self.cids = []
+        """Clear axes and disable mouse button callbacks.
+        """
+        self.disable_mouse_rotation()
         Axes.cla(self)
         self.grid(rcParams['axes3d.grid'])
 
+    def disable_mouse_rotation(self):
+        """Disable mouse button callbacks.
+        """
+        # Disconnect the various events we set.
+        for cid in self._cids:
+            self.figure.canvas.mpl_disconnect(cid)
+
+        self._cids = []
+
     def _button_press(self, event):
         if event.inaxes == self:
             self.button_pressed = event.button
@@ -426,9 +457,10 @@
     def _on_move(self, event):
         """Mouse moving
 
-        button-1 rotates
-        button-3 zooms
+        button-1 rotates by default.  Can be set explicitly in mouse_init().
+        button-3 zooms by default.  Can be set explicitly in mouse_init().
         """
+
         if not self.button_pressed:
             return
 
@@ -447,7 +479,8 @@
         h = (y1-y0)
         self.sx, self.sy = x, y
 
-        if self.button_pressed == 1:
+        # Rotation
+        if self.button_pressed in self._rotate_btn:
             # rotate viewing point
             # get the x and y pixel coords
             if dx == 0 and dy == 0:
@@ -456,12 +489,15 @@
             self.azim = art3d.norm_angle(self.azim - (dx/w)*180)
             self.get_proj()
             self.figure.canvas.draw()
-        elif self.button_pressed == 2:
+
+#        elif self.button_pressed == 2:
             # pan view
             # project xv,yv,zv -> xw,yw,zw
             # pan
-            pass
-        elif self.button_pressed == 3:
+#            pass
+
+        # Zoom
+        elif self.button_pressed in self._zoom_btn:
             # zoom view
             # hmmm..this needs some help from clipping....
             minx, maxx, miny, maxy, minz, maxz = self.get_w_lims()
@@ -476,7 +512,7 @@
             self.figure.canvas.draw()
 
     def set_xlabel(self, xlabel, fontdict=None, **kwargs):
-        '''Set xlabel. '''
+        '''Set xlabel.'''
 
         label = self.w_xaxis.get_label()
         label.set_text(xlabel)
@@ -511,13 +547,18 @@
         '''
         self._draw_grid = on
 
-    def text(self, x, y, z, s, zdir=None):
-        '''Add text to the plot.'''
-        text = Axes.text(self, x, y, s)
+    def text(self, x, y, z, s, zdir=None, **kwargs):
+        '''
+        Add text to the plot. kwargs will be passed on to Axes.text,
+        except for the `zdir` keyword, which sets the direction to be
+        used as the z direction.
+        '''
+        text = Axes.text(self, x, y, s, **kwargs)
         art3d.text_2d_to_3d(text, z, zdir)
         return text
 
     text3D = text
+    text2D = Axes.text
 
     def plot(self, xs, ys, *args, **kwargs):
         '''
@@ -591,6 +632,9 @@
         *shade*     Whether to shade the facecolors, default:
                     false when cmap specified, true otherwise
         ==========  ================================================
+
+        Other arguments are passed on to
+        :func:`~mpl_toolkits.mplot3d.art3d.Poly3DCollection.__init__`
         '''
 
         had_data = self.has_data()
@@ -822,8 +866,9 @@
 
             colors = self._shade_colors(color, normals)
             colors2 = self._shade_colors(color, normals)
-            polycol = art3d.Poly3DCollection(polyverts, facecolors=colors,
-                edgecolors=colors2)
+            polycol = art3d.Poly3DCollection(polyverts,
+                                             facecolors=colors,
+                                             edgecolors=colors2)
             polycol.set_sort_zpos(z)
             self.add_collection3d(polycol)
 
@@ -848,6 +893,8 @@
 
         Other keyword arguments are passed on to
         :func:`~matplotlib.axes.Axes.contour`
+
+        Returns a :class:`~matplotlib.axes.Axes.contour`
         '''
 
         extend3d = kwargs.pop('extend3d', False)
@@ -881,7 +928,9 @@
         *X*, *Y*, *Z*: data points.
 
         Keyword arguments are passed on to
-        :func:`~matplotlib.axes.Axes.contour`
+        :func:`~matplotlib.axes.Axes.contourf`
+
+        Returns a :class:`~matplotlib.axes.Axes.contourf`
         '''
 
         had_data = self.has_data()
@@ -1005,25 +1054,61 @@
 
         return patches
 
-    def bar3d(self, x, y, z, dx, dy, dz, color='b'):
+    def bar3d(self, x, y, z, dx, dy, dz, color='b',
+              zsort='average', *args, **kwargs):
         '''
         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.
+        dx, dy, dz can be arrays or scalars.
+
+        *color* can be:
+         - A single color value, to color all bars the same color.
+         - An array of colors of length N bars, to color each bar
+         independently.
+         - An array of colors of length 6, to color the faces of the bars
+         similarly.
+         - An array of colors of length 6 * N bars, to color each face
+         independently.
+
+         When coloring the faces of the boxes specifically, this is the order
+         of the coloring:
+          1. -Z (bottom of box)
+          2. +Z (top of box)
+          3. -Y
+          4. +Y
+          5. -X
+          6. +X
+
+        Keyword arguments are passed onto
+        :func:`~mpl_toolkits.mplot3d.art3d.Poly3DCollection`
         '''
-
         had_data = self.has_data()
 
         if not cbook.iterable(x):
-            x, y, z = [x], [y], [z]
+            x = [x]
+        if not cbook.iterable(y):
+            y = [y]
+        if not cbook.iterable(z):
+            z = [z]
+
         if not cbook.iterable(dx):
-            dx, dy, dz = [dx], [dy], [dz]
+            dx = [dx]
+        if not cbook.iterable(dy):
+            dy = [dy]
+        if not cbook.iterable(dz):
+            dz = [dz]
+
         if len(dx) == 1:
             dx = dx * len(x)
-            dy = dy * len(x)
-            dz = dz * len(x)
+        if len(dy) == 1:
+            dy = dy * len(y)
+        if len(dz) == 1:
+            dz = dz * len(z)
 
+        if len(x) != len(y) or len(x) != len(z):
+            warnings.warn('x, y, and z must be the same length.')
+
         minx, miny, minz = 1e20, 1e20, 1e20
         maxx, maxy, maxz = -1e20, -1e20, -1e20
 
@@ -1053,15 +1138,35 @@
                     (xi + dxi, yi + dyi, zi + dzi), (xi + dxi, yi, zi + dzi)),
             ])
 
-        color = np.array(colorConverter.to_rgba(color))
+        facecolors = []
+        if color is None:
+            # no color specified
+            facecolors = [None] * len(x)
+        elif len(color) == len(x):
+            # bar colors specified, need to expand to number of faces
+            for c in color:
+                facecolors.extend([c] * 6)
+        else:
+            # a single color specified, or face colors specified explicitly
+            facecolors = list(colorConverter.to_rgba_array(color))
+            if len(facecolors) < len(x):
+                facecolors *= (6 * len(x))
+
         normals = self._generate_normals(polys)
-        colors = self._shade_colors(color, normals)
-
-        col = art3d.Poly3DCollection(polys, facecolor=colors)
+        sfacecolors = self._shade_colors(facecolors, normals)
+        col = art3d.Poly3DCollection(polys,
+                                     zsort=zsort,
+                                     facecolor=sfacecolors,
+                                     *args, **kwargs)
         self.add_collection(col)
 
         self.auto_scale_xyz((minx, maxx), (miny, maxy), (minz, maxz), had_data)
 
+    def set_title(self, label, fontdict=None, **kwargs):
+        Axes.set_title(self, label, fontdict, **kwargs)
+        (x, y) = self.title.get_position()
+        self.title.set_y(0.92 * y)
+
 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.

------------------------------------------------------------------------------
Download Intel&#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
Matplotlib-checkins mailing list
Matplotlib-checkins@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins

Reply via email to