--- C:\home\mspacek\Desktop\axes.svn2508.py 2006-06-22 19:04:36.000000000 -0700 +++ C:\home\mspacek\Desktop\axes.patch5.py 2006-06-22 23:10:53.000000000 -0700 @@ -2361,185 +2361,243 @@ #### Specialized plotting 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) - - patches = [] - + width = asarray(width) + bottom = asarray(bottom) # 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) + + bottom, width, height, and left can be either scalars or sequences - Return value is a list of Rectangle patch instances + 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 ecolor specifies the color of any errorbar 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 = [] - - - # 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) - + This enables you to use barh as the basis for stacked bar + charts, or candlestick plots + """ - 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() + 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 + def stem(self, x, y, linefmt='b-', markerfmt='bo', basefmt='r-'): """ STEM(x, y, linefmt='b-', markerfmt='bo', basefmt='r-') A stem plot plots vertical lines (using linefmt) at each x location @@ -3975,42 +4033,47 @@ return table.table(self, **kwargs) #### 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. The return values is (n, bins, patches) If normed is true, the first element of the return tuple will 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. kwargs are used to update the properties of the 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) def psd(self, x, NFFT=256, Fs=2, detrend=detrend_none, window=window_hanning, noverlap=0, **kwargs):