John Hunter wrote:
> I can live with that -- did you test your work with the table_demo?

I just tried table_demo, looks good, bars are nicely centered (had to set my rcparams axes.hold to True to get all four colours of bars).

I'm having trouble applying your patch because of the way the file
names are coded.  If somebody knows the magic patch command to make it
go through, please commit it.  Otherwise, Martin, can you make a patch
with svn diff from the mpl root dir (the one that setup.py lives in)?

Ah, I was just working off the axes.py file from viewcvs. I've checked out now from /trunk/matplotlib/ (using tortoise svn). Hopefully this new patch file will work.

Cheers,

Martin
Index: lib/matplotlib/axes.py
===================================================================
--- lib/matplotlib/axes.py      (revision 2514)
+++ lib/matplotlib/axes.py      (working copy)
@@ -2364,114 +2364,213 @@
 
 
     def bar(self, left, height, width=0.8, bottom=0,
-            color='b', yerr=None, xerr=None, ecolor='k', capsize=3
+            color=None, edgecolor=None, yerr=None, xerr=None, ecolor=None, 
capsize=3,
+            align='edge', orientation='vertical'
             ):
         """
         BAR(left, height, width=0.8, bottom=0,
-            color='b', yerr=None, xerr=None, ecolor='k', capsize=3)
+            color=None, edgecolor=None, yerr=None, xerr=None, ecolor=None, 
capsize=3,
+            align='edge', orientation='vertical')
 
-        Make a bar plot with rectangles at
+        Make a bar plot with rectangles bounded by
 
-          left, left+width, 0, height
+          left, left+width, bottom, bottom+height  (left, right, bottom and 
top edges)
 
-        left and height are Numeric arrays.
+        left, height, width, and bottom can be either scalars or sequences
 
         Return value is a list of Rectangle patch instances
 
         BAR(left, height, width, bottom,
-            color, yerr, xerr, capsize, yoff)
+            color, edgecolor, yerr, xerr, ecolor, capsize,
+            align, orientation)
 
+            left - the x coordinates of the left sides of the bars
+
+            height - the heights of the bars
+
+        Optional arguments
+
+            width - the widths of the bars
+
+            bottom - the y coordinates of the bottom edges of the bars
+
+            color specifies the colors of the bars
+
+            edgecolor specifies the colors of the bar edges
+
             xerr and yerr, if not None, will be used to generate errorbars
-              on the bar chart
+            on the bar chart
 
-            color specifies the color of the bar
-
             ecolor specifies the color of any errorbar
 
             capsize determines the length in points of the error bar caps
 
+            align = 'edge' | 'center'
 
-        The optional arguments color, width and bottom can be either
-        scalars or len(x) sequences
+            orientation = 'vertical' | 'horizontal'
 
+            For vertical bars, 'edge' aligns bars by their left edges in left,
+            while 'center' interprets these values as the x coordinates of the 
bar centers.
+            For horizontal bars, 'edge' aligns bars by their bottom edges in 
bottom,
+            while 'center' interprets these values as the y coordinates of the 
bar centers.
+
+        The optional arguments color, edgecolor, yerr, and xerr can be either
+        scalars or sequences of length equal to the number of bars
+
         This enables you to use bar as the basis for stacked bar
         charts, or candlestick plots
         """
         if not self._hold: self.cla()
 
-        # left = asarray(left) - width/2
+        def make_iterable(x):
+            if not iterable(x):
+                return [x]
+            else:
+                return x
+
+        # make them safe to take len() of
+        left = make_iterable(left)
+        height = make_iterable(height)
+        width = make_iterable(width)
+        bottom = make_iterable(bottom)
+
+        if orientation == 'vertical':
+            # size width and bottom according to length of left
+            nbars = len(left)
+            if len(width) == 1:
+                width *= nbars
+            if len(bottom) == 1:
+                bottom *= nbars
+        elif orientation == 'horizontal':
+            # size left and height according to length of bottom
+            nbars = len(bottom)
+            if len(left) == 1:
+                left *= nbars
+            if len(height) == 1:
+                height *= nbars
+        else:
+            raise ValueError, 'invalid orientation: %s' % orientation
+
         left = asarray(left)
         height = asarray(height)
+        width = asarray(width)
+        bottom = asarray(bottom)
 
-        patches = []
-
-
         # if color looks like a color string, an RGB tuple or a
-        # scalar, then repeat it by len(x)
+        # scalar, then repeat it by nbars
         if (is_string_like(color) or
-            (iterable(color) and len(color)==3 and len(left)!=3) or
+            (iterable(color) and len(color)==3 and nbars!=3) or
             not iterable(color)):
-            color = [color]*len(left)
+            color = [color]*nbars
 
+        # if edgecolor looks like a color string, an RGB tuple or a
+        # scalar, then repeat it by nbars
+        if (is_string_like(edgecolor) or
+            (iterable(edgecolor) and len(edgecolor)==3 and nbars!=3) or
+            not iterable(edgecolor)):
+            edgecolor = [edgecolor]*nbars
 
-        if not iterable(bottom):
-            bottom = array([bottom]*len(left), Float)
+        if not iterable(yerr):
+            yerr = asarray([yerr]*nbars, Float) # Float converts Nones to NANs
         else:
-            bottom = asarray(bottom)
-        if not iterable(width):
-            width = array([width]*len(left), Float)
+            yerr = asarray(yerr)
+        if not iterable(xerr):
+            xerr = asarray([xerr]*nbars, Float)
         else:
-            width = asarray(width)
+            xerr = asarray(xerr)
 
-        N = len(left)
-        assert len(bottom)==N, 'bar arg bottom must be len(left)'
-        assert len(width)==N, 'bar arg width must be len(left) or scalar'
-        assert len(height)==N, 'bar arg height must be len(left) or scalar'
-        assert len(color)==N, 'bar arg color must be len(left) or scalar'
+        if orientation == 'vertical':
+            lenarg = 'left'
+        elif orientation == 'horizontal':
+            lenarg = 'bottom'
+        assert len(left)==nbars, 'bar() argument \'left\' must be len(%s) or 
scalar' % lenarg
+        assert len(height)==nbars, 'bar() argument \'height\' must be len(%s) 
or scalar' % lenarg
+        assert len(width)==nbars, 'bar() argument \'width\' must be len(%s) or 
scalar' % lenarg
+        assert len(bottom)==nbars, 'bar() argument \'bottom\' must be len(%s) 
or scalar' % lenarg
+        assert len(color)==nbars, 'bar() argument \'color\' must be len(%s) or 
scalar' % lenarg
+        assert len(edgecolor)==nbars, 'bar() argument \'edgecolor\' must be 
len(%s) or scalar' % lenarg
+        assert len(yerr)==nbars, 'bar() argument \'yerr\' must be len(%s) or 
scalar' % lenarg
+        assert len(xerr)==nbars, 'bar() argument \'xerr\' must be len(%s) or 
scalar' % lenarg
 
-        args = zip(left, bottom, width, height, color)
-        for l, b, w, h, c in args:
+        patches = []
+
+        if align == 'edge':
+            pass
+        elif align == 'center':
+            if orientation == 'vertical':
+                left = left - width/2.
+            elif orientation == 'horizontal':
+                bottom = bottom - height/2.
+        else:
+            raise ValueError, 'invalid alignment: %s' % align
+
+        args = zip(left, bottom, width, height, color, edgecolor)
+        for l, b, w, h, c, e in args:
             if h<0:
                 b += h
                 h = abs(h)
             r = Rectangle(
                 xy=(l, b), width=w, height=h,
                 facecolor=c,
+                edgecolor=e,
                 )
             self.add_patch(r)
             patches.append(r)
 
+        holdstate = self._hold
+        self.hold(True) # ensure hold is on before plotting errorbars
 
         if xerr is not None or yerr is not None:
+            if orientation == 'vertical':
+                x, y = left+0.5*width, bottom+height
+            elif orientation == 'horizontal':
+                x, y = left+width, bottom+0.5*height
             self.errorbar(
-                left+0.5*width, bottom+height,
+                x, y,
                 yerr=yerr, xerr=xerr,
                 fmt=None, ecolor=ecolor, capsize=capsize)
+
+        self.hold(holdstate) # restore previous hold state
+
         self.autoscale_view()
         return patches
 
-    def barh(self, x, y, height=0.8, left=0,
-            color='b', yerr=None, xerr=None, ecolor='k', capsize=3
-            ):
+
+    def barh(self, bottom, width, height=0.8, left=0,
+             color=None, edgecolor=None, xerr=None, yerr=None, ecolor=None, 
capsize=3,
+             align='edge'
+             ):
         """
-        BARH(x, y, height=0.8, left=0,
-             color='b', yerr=None, xerr=None, ecolor='k', capsize=3)
+        BARH(bottom, width, height=0.8, left=0,
+             color=None, edgecolor=None, xerr=None, yerr=None, ecolor=None, 
capsize=3,
+             align='edge')
 
-            BARH(x, y)
+        Make a horizontal bar plot with rectangles bounded by
 
-            The y values give the heights of the center of the bars.  The
-            x values give the length of the bars.
+          left, left+width, bottom, bottom+height  (left, right, bottom and 
top edges)
 
-            Return value is a list of Rectangle patch instances
+        bottom, width, height, and left can be either scalars or sequences
 
+        Return value is a list of Rectangle patch instances
+
+        BARH(bottom, width, height, left,
+             color, edgecolor, xerr, yerr, ecolor, capsize,
+             align)
+
+            bottom - the vertical positions of the bottom edges of the bars
+
+            width - the lengths of the bars
+
         Optional arguments
 
-            height - the height (thickness)  of the bar
+            height - the heights (thicknesses) of the bars
 
-            left  - the x coordinate of the left side of the bar
+            left - the x coordinates of the left edges of the bars
 
-            color specifies the color of the bar
+            color specifies the colors of the bars
 
+            edgecolor specifies the colors of the bar edges
+
             xerr and yerr, if not None, will be used to generate errorbars
             on the bar chart
 
@@ -2479,65 +2578,24 @@
 
             capsize determines the length in points of the error bar caps
 
-        The optional arguments color, height and left can be either
-        scalars or len(x) sequences
-        """
-        if not self._hold: self.cla()
+            align = 'edge' | 'center'
+            'edge' aligns the horizontal bars by their bottom edges in bottom, 
while
+            'center' interprets these values as the y coordinates of the bar 
centers.
 
-        # left = asarray(left) - width/2
-        x = asarray(x)
-        y = asarray(y)
+        The optional arguments color, edgecolor, xerr, and yerr can be either
+        scalars or sequences of length equal to the number of bars
 
-        patches = []
+        This enables you to use barh as the basis for stacked bar
+        charts, or candlestick plots
+        """
 
+        patches = self.bar(left=left, height=height, width=width, 
bottom=bottom,
+                           color=color, edgecolor=edgecolor, yerr=yerr, 
xerr=xerr, ecolor=ecolor, capsize=capsize,
+                           align=align, orientation='horizontal'
+                           )
+        return patches
 
-        # if color looks like a color string, and RGB tuple or a
-        # scalar, then repeat it by len(x)
-        if (is_string_like(color) or
-                    (iterable(color) and len(color)==3 and
-                     iterable(left) and len(left)!=3) or not iterable(color)):
-            color = [color]*len(x)
 
-
-        if not iterable(left):
-            left = array([left]*len(x), Float)
-        else:
-            left = asarray(left)
-        if not iterable(height):
-            height = array([height]*len(x), Float)
-        else:
-            height = asarray(height)
-
-        N = len(x)
-        assert len(left)==N, 'bar arg left must be len(x)'
-        assert len(height)==N, 'bar arg height must be len(x) or scalar'
-        assert len(y)==N, 'bar arg y must be len(x) or scalar'
-        assert len(color)==N, 'bar arg color must be len(x) or scalar'
-
-        width = x
-        right = left+x
-        bottom = y - height/2.
-
-        args = zip(left, bottom, width, height, color)
-        for l, b, w, h, c in args:
-            if h<0:
-                b += h
-                h = abs(h)
-            r = Rectangle(
-                xy=(l, b), width=w, height=h,
-                facecolor=c,
-                )
-            self.add_patch(r)
-            patches.append(r)
-
-        if xerr is not None or yerr is not None:
-            self.errorbar(
-                right, y,
-                yerr=yerr, xerr=xerr,
-                fmt=None, ecolor=ecolor, capsize=capsize)
-        self.autoscale_view()
-        return patches
-
     def stem(self, x, y, linefmt='b-', markerfmt='bo', basefmt='r-'):
         """
         STEM(x, y, linefmt='b-', markerfmt='bo', basefmt='r-')
@@ -3978,9 +4036,10 @@
     #### Data analysis
 
     def hist(self, x, bins=10, normed=0, bottom=0,
-             orientation='vertical', width=None, **kwargs):
+             align='edge', orientation='vertical', width=None, **kwargs):
         """
-        HIST(x, bins=10, normed=0, bottom=0, orientiation='vertical', **kwargs)
+        HIST(x, bins=10, normed=0, bottom=0,
+             align='edge', orientation='vertical', width=None, **kwargs)
 
         Compute the histogram of x.  bins is either an integer number of
         bins or a sequence giving the bins.  x are the data to be binned.
@@ -3991,9 +4050,11 @@
         be the counts normalized to form a probability density, ie,
         n/(len(x)*dbin)
 
+        align = 'edge' | 'center'.  Interprets bins either as edge
+        or center values
 
         orientation = 'horizontal' | 'vertical'.  If horizontal, barh
-        will be used and the "bottom" kwarg will be the left.
+        will be used and the "bottom" kwarg will be the left edges.
 
         width: the width of the bars.  If None, automatically compute
         the width.
@@ -4002,12 +4063,14 @@
         hist bars
         """
         if not self._hold: self.cla()
-        n,bins = matplotlib.mlab.hist(x, bins, normed)
+        n, bins = matplotlib.mlab.hist(x, bins, normed)
         if width is None: width = 0.9*(bins[1]-bins[0])
-        if orientation=='horizontal':
-            patches = self.barh(n, bins, height=width, left=bottom)
+        if orientation == 'horizontal':
+            patches = self.barh(bins, n, height=width, left=bottom, 
align=align)
+        elif orientation == 'vertical':
+            patches = self.bar(bins, n, width=width, bottom=bottom, 
align=align)
         else:
-            patches = self.bar(bins, n, width=width, bottom=bottom)
+            raise ValueError, 'invalid orientation: %s' % orientation
         for p in patches:
             p.update(kwargs)
         return n, bins, silent_list('Patch', patches)
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel

Reply via email to