Hi John,
John Hunter wrote:
Most people prefer the center aligning behavior, at least those who
complained on the list about bar, so when I wrote barh I adopted
this. I tried to fix bar in the process, but ended up running into
some bugs when I tested John Gill's table demo, and so left it as edge
aligned and haven't revisited it since. So my weak preference would
be to have the two functions consistent and center aligned, but he who
does the work usually gets the biggest vote. Maybe others can chime
in.
I suppose I'm a bit jaded towards edges because I tend to make
histograms and not bar graphs, but we can have it both ways.
Here's patch5 (now against the latest axes.py rev 2508). It has
everything in patch4, plus a keyword arg 'align' that lets you choose
between aligning the bars according to their edges (left for vertical
bars, bottom for horizontal bars) or their centers. The default is
align='edge' for both bar() and barh(). Perhaps that should be changed
to 'center' if most people prefer it that way. Also, the 'horizontal'
boolean arg in patch4 has been renamed to 'orientation' and is now a
string: either 'vertical' or 'horizontal', consistent with hist(). I
also added the align arg to hist(), which just passes it on to bar() or
barh().
I was following the convention that the x arg goes first and the y
second, but I'm not wed to this.
In barh(), Matlab does indeed order the args x, y, but interprets them
as y, x (ie, position, value), which actually makes sense to me.
Perhaps you could patch the CHANGELOG and
API_CHANGES file along with the rest which explains the changes.
Sure. Here they are against their latest rev (2508 for both). Never done
logs before, hope they're alright. What do you mean by "the rest"?
Cheers,
Martin
--- 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):
--- C:\home\mspacek\Desktop\API_CHANGES.2508.txt 2006-06-22
22:11:57.000000000 -0700
+++ C:\home\mspacek\Desktop\API_CHANGES 2006-06-22 22:54:24.000000000 -0700
@@ -1,6 +1,21 @@
+ barh: x and y args have been renamed to width and bottom
+ respectively, and their order has been swapped to maintain
+ a (position, value) order.
+
+ bar and barh: now accept kwarg 'edgecolor'.
+
+ bar and barh: The left, height, width and bottom args can
+ now all be scalars or sequences; see docstring.
+
+ barh: now defaults to edge aligned instead of center
+ aligned bars
+
+ bar, barh and hist: Added a keyword arg 'align' that
+ controls between edge or center bar alignment.
+
Collections: PolyCollection and LineCollection now accept
vertices or segments either in the original form [(x,y),
(x,y), ...] or as a 2D numerix array, with X as the first column
and Y as the second. Contour and quiver output the numerix
form. The transforms methods Bbox.update() and
Transformation.seq_xy_tups() now accept either form.
--- C:\home\mspacek\Desktop\CHANGELOG.rev2508.txt 2006-06-22
22:13:15.000000000 -0700
+++ C:\home\mspacek\Desktop\CHANGELOG 2006-06-22 22:38:38.000000000 -0700
@@ -1,5 +1,21 @@
+2006-06-22 Various changes to bar(), barh(), and hist().
+ Added 'edgecolor' keyword arg to bar() and barh().
+ The x and y args in barh() have been renamed to width
+ and bottom respectively, and their order has been swapped
+ to maintain a (position, value) order ala matlab. left,
+ height, width and bottom args can now all be scalars or
+ sequences. barh() now defaults to edge alignment instead
+ of center alignment. Added a keyword arg 'align' to bar(),
+ barh() and hist() that controls between edge or center bar
+ alignment. Fixed ignoring the rcParams['patch.facecolor']
+ for bar color in bar() and barh(). Fixed ignoring the
+ rcParams['lines.color'] for error bar color in bar()
+ and barh(). Fixed a bug where patches would be cleared
+ when error bars were plotted if rcParams['axes.hold']
+ was False. - MAS
+
2006-06-22 Added support for numerix 2-D arrays as alternatives to
a sequence of (x,y) tuples for specifying paths in
collections, quiver, contour, pcolor, transforms.
Fixed contour bug involving setting limits for
color mapping. Added numpy-style all() to numerix. - EF
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