# Histogram align 'edge' or 'center' bug?

David Fokkema <dfokkema@...1511...> writes:

I can't think of an application where you have bins of different
widths and you want to center the values...

Actually, now that I think about it, there is not enough information
in the bin centers to know the widths of the bins if they may vary.
For example, if your bin edges are (2, 4, 8, 16, 32) or (1, 5, 7, 17,
31), you get the same bin centers (3, 6, 12, 24). Perhaps it's best to
disallow variable-width bins when align='center'.

···

--
Jouni K. Sepp�nen

Of course! Nice example, I've changed the documentation strings.
What do you think of this patch? Shall I send it upstream as a bug
report with attached patch?

David

--- matplotlib/axes.py.orig 2007-04-12 09:52:47.000000000 +0200
+++ matplotlib/axes.py 2007-04-12 14:26:08.000000000 +0200
@@ -4137,19 +4137,21 @@
n/(len(x)*dbin)

align = 'edge' | 'center'. Interprets bins either as edge
- or center values
+ or center values. If 'center', the bins are interpreted as equally
+ sized.

orientation = 'horizontal' | 'vertical'. If horizontal, barh
will be used and the "bottom" kwarg will be the left edges.

width: the width of the bars. If None, automatically compute
- the width.
+ the width. If align = 'center', the bins are interpreted as
+ equally sized.

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, align)
if width is None: width = 0.9*(bins-bins)
if orientation == 'horizontal':
patches = self.barh(bins, n, height=width, left=bottom,
align=align)
--- matplotlib/mlab.py.orig 2007-04-12 09:52:47.000000000 +0200
+++ matplotlib/mlab.py 2007-04-12 14:25:30.000000000 +0200
@@ -597,7 +597,7 @@
#S = -1.0*asum(p*log(p))
return S

-def hist(y, bins=10, normed=0):
+def hist(y, bins=10, normed=0, align='edge'):
"""
Return the histogram of y with bins equally sized bins. If bins
is an array, use the bins. Return value is
@@ -605,7 +605,12 @@

If normed is False, return the counts in the first element of the
return tuple. If normed is True, return the probability density
- n/(len(y)*dbin)
+ n/(len(y)*dbin). If normed is True, the bins are interpreted as
+ equally sized.

···

On Tue, 2007-04-10 at 19:03 +0300, Jouni K. Seppänen wrote:

David Fokkema <dfokkema@...1511...> writes:

> I can't think of an application where you have bins of different
> widths and you want to center the values...

Actually, now that I think about it, there is not enough information
in the bin centers to know the widths of the bins if they may vary.
For example, if your bin edges are (2, 4, 8, 16, 32) or (1, 5, 7, 17,
31), you get the same bin centers (3, 6, 12, 24). Perhaps it's best to
disallow variable-width bins when align='center'.

+
+ align = 'edge' | 'center'. Interprets bins either as edge
+ or center values. If 'center', the bins are interpreted as equally
+ sized.

If y has rank>1, it will be raveled
Credits: the Numeric 22 documentation
@@ -626,11 +631,16 @@
dy = (ymax-ymin)/bins
bins = ymin + dy*arange(bins)

+ if align == 'center':
+ hw = .5*(bins-bins)
+ nbins = [x-hw for x in bins]
+ else:
+ nbins = bins

- n = searchsorted(sort(y), bins)
+ n = searchsorted(sort(y), nbins)
n = diff(concatenate([n, [len(y)]]))
if normed:
- db = bins-bins
+ db = nbins-nbins
return 1/(len(y)*db)*n, bins
else:
return n, bins