bar() in matlab

Jin-chung> When I do the bar(left, height) in matlab the first
    Jin-chung> time, e.g.:
    >>>> bar([4,5,6,7,8],[9,8,7,6,5])

Hi, thanks for the report.

This was a bug in the way I update the datalim in axes.py, which is
currently a bit too fragile for my tastes. Below I'll include the
modified matplotlib.axes.Axes.bar function. Let me know if it passes
all your tests...

Cheers,
JDH

    def bar(self, left, height, width=0.8, bottom=0,
            color='b', yerr=None, xerr=None, ecolor='k', capsize=3
            ):
        """
        BAR(left, height)
        
        Make a bar plot with rectangles at
          left, left+width, 0, height
        left and height are Numeric arrays

        Return value is a list of Rectangle patch instances

        BAR(left, height, width, bottom,
            color, yerr, xerr, capsize, yoff)

        xerr and yerr, if not None, will be used to generate errorbars
        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

        The optional arguments color, width and bottom can be either
        scalars or len(x) sequences

        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)
        height = asarray(height)

        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 len(left)!=3) or
            not iterable(color)):
            color = [color]*len(left)

        if not iterable(bottom):
            bottom = array([bottom]*len(left), Float)
        else:
            bottom = asarray(bottom)
        if not iterable(width):
            width = array([width]*len(left), Float)
        else:
            width = asarray(width)

        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'

        right = left + width
        top = bottom + height
        
        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(
                left+0.5*width, bottom+height,
                yerr=yerr, xerr=xerr,
                fmt=None, ecolor=ecolor, capsize=capsize)
        self.autoscale_view()
        return patches

I was interested in this report, and sorry if I butted in. John's patch
fixes Jin-chung's problem with poor x-axis scaling here. I'm using CVS,
not 0.60.2, and didn't see the "funny Y tick labels" he reported.

However, in either case, the bars' left edge is at the x coordinate
rather than being centered on it. I know this is the documented
behavior, but Matlab centers the bars on the given X coordinates. How
do people feel about changing matplotlib to match the Matlab behavior?
I've changed my copy locally.

···

On Thu, 2004-08-05 at 10:00, John Hunter wrote:

    Jin-chung> When I do the bar(left, height) in matlab the first
    Jin-chung> time, e.g.:
    >>>> bar([4,5,6,7,8],[9,8,7,6,5])

This was a bug in the way I update the datalim in axes.py, which is
currently a bit too fragile for my tastes. Below I'll include the
modified matplotlib.axes.Axes.bar function. Let me know if it passes
all your tests...

--
Stephen Walton <stephen.walton@...267...>
Dept. of Physics & Astronomy, Cal State Northridge