Skip to content

Commit d3f139f

Browse files
committed
bugfix: mlab.prctile handles even-length data
svn path=/trunk/matplotlib/; revision=8039
1 parent cdd5fac commit d3f139f

File tree

2 files changed

+34
-11
lines changed

2 files changed

+34
-11
lines changed

CHANGELOG

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
2009-12-18 mlab.prctile handles even-length data, such that the median
2+
is the mean of the two middle values. - ADS
3+
14
2009-12-15 Add raw-image (unsampled) support for the ps backend. - JJL
25

36
2009-12-14 Add patch_artist kwarg to boxplot, but keep old default.

lib/matplotlib/mlab.py

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -904,18 +904,38 @@ def prctile(x, p = (0.0, 25.0, 50.0, 75.0, 100.0)):
904904
the *p* percentage point in the sequence is returned.
905905
"""
906906

907+
# This implementation derived from scipy.stats.scoreatpercentile
908+
def _interpolate(a, b, fraction):
909+
"""Returns the point at the given fraction between a and b, where
910+
'fraction' must be between 0 and 1.
911+
"""
912+
return a + (b - a)*fraction
913+
914+
scalar = True
915+
if cbook.iterable(p):
916+
scalar = False
917+
per = np.array(p)
918+
values = np.array(x).ravel() # copy
919+
values.sort()
920+
921+
idxs = per /100. * (values.shape[0] - 1)
922+
ai = idxs.astype(np.int)
923+
bi = ai + 1
924+
frac = idxs % 1
925+
926+
# handle cases where attempting to interpolate past last index
927+
cond = bi >= len(values)
928+
if scalar:
929+
if cond:
930+
ai -= 1
931+
bi -= 1
932+
frac += 1
933+
else:
934+
ai[cond] -= 1
935+
bi[cond] -= 1
936+
frac[cond] += 1
907937

908-
x = np.array(x).ravel() # we need a copy
909-
x.sort()
910-
Nx = len(x)
911-
912-
if not cbook.iterable(p):
913-
return x[int(p*Nx/100.0)]
914-
915-
p = np.asarray(p)* Nx/100.0
916-
ind = p.astype(int)
917-
ind = np.where(ind>=Nx, Nx-1, ind)
918-
return x.take(ind)
938+
return _interpolate(values[ai],values[bi],frac)
919939

920940
def prctile_rank(x, p):
921941
"""

0 commit comments

Comments
 (0)