8000 aaplied several sf patches · matplotlib/matplotlib@204216e · GitHub
[go: up one dir, main page]

Skip to content

Commit 204216e

Browse files
committed
aaplied several sf patches
svn path=/trunk/matplotlib/; revision=1098
1 parent 8ddeee3 commit 204216e

File tree

6 files changed

+225
-19
lines changed

6 files changed

+225
-19
lines changed

CHANGELOG

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
New entries should be added at the top
22

3+
2005-03-28 Applied boxplot and OSX font search patches
34

45
2005-03-27 Added ft2font NULL check to fix Japanase font bug - JDH
56

boilerplate.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ def %(func)s(*args, **kwargs):
4848
'axvspan',
4949
'bar',
5050
'barh',
51+
'boxplot',
5152
'cohere',
5253
'clabel',
5354
'contour',

lib/matplotlib/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
axis - Set or return the current axis limits
1616
bar - make a bar chart
1717
barh - a horizontal bar chart
18+
boxplot - make a box and whisker plot
1819
cla - clear current axes
1920
clf - clear a figure window
2021
close - close a figure window

lib/matplotlib/axes.py

Lines changed: 149 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from numerix import absolute, arange, array, asarray, ones, divide,\
66
transpose, log, log10, Float, Float32, ravel, zeros,\
77
Int16, Int32, Int, Float64, ceil, indices, \
8-
shape, which, where, sqrt, asum
8+
shape, which, where, sqrt, asum, compress
99

1010
import matplotlib.mlab
1111
from artist import Artist
@@ -27,7 +27,7 @@
2727
from lines import Line2D, lineStyles, lineMarkers
2828

2929
from matplotlib.mlab import meshgrid, detrend_none, detrend_linear, \
30-
window_none, window_hanning, linspace
30+
window_none, window_hanning, linspace, prctile
3131
from matplotlib.numerix.mlab import flipud, amin, amax
3232

3333
from matplotlib import rcParams
@@ -845,7 +845,154 @@ def bar(self, left, height, width=0.8, bottom=0,
845845
self.autoscale_view()
846846
return patches
847847

848+
def boxplot(self, x, notch=0, sym='b+', vert=1, whis=1.5):
849+
"""
850+
boxplot(x, notch=0, sym='+', vert=1, whis=1.5)
851+
852+
Make a box and whisker plot for each column of x.
853+
The box extends from the lower to upper quartile values
854+
of the data, with a line at the median. The whiskers
855+
extend from the box to show the range of the data. Flier
856+
points are those past the end of the whiskers.
857+
858+
notch = 0 (default) produces a rectangular box plot.
859+
notch = 1 will produce a notched box plot
860+
861+
sym (default 'b+') is the default symbol for flier points.
862+
Enter an empty string ('') if you don't want to show fliers.
863+
864+
vert = 1 (default) makes the boxes vertical.
865+
vert = 0 makes horizontal boxes. This seems goofy, but
866+
that's how Matlab did it.
867+
868+
whis (default 1.5) defines the length of the whiskers as
869+
a function of the inner quartile range. They extend to the
870+
most extreme data point within ( whis*(75%-25%) ) data range.
848871
872+
x is a Numeric array
873+
874+
Returns a list of the lines added
875+
876+
"""
877+
if not F438 self._hold: self.cla()
878+
holdStatus = self._hold
879+
lines = []
880+
x = asarray(x)
881+
882+
# if we've got a vector, reshape it
883+
rank = len(x.shape)
884+
if 1 == rank:
885+
x.shape(-1, 1)
886+
887+
row, col = x.shape
888+
889+
# get some plot info
890+
num_plots = range(1, col + 1)
891+
box_width = col * min(0.15, 0.5/col)
892+
893+
# loop through columns, adding each to plot
894+
self.hold(True)
895+
for i in num_plots:
896+
d = x[:,i-1]
897+
# get median and quartiles
898+
q1, med, q3 = prctile(d,[25,50,75])
899+
# get high extreme
900+
iq = q3 - q1
901+
hi_val = q3 + whis*iq
902+
wisk_hi = compress( d <= hi_val , d )
903+
if len(wisk_hi) == 0:
904+
wisk_hi = q3
905+
else:
906+
wisk_hi = max(wisk_hi)
907+
# get low extreme
908+
lo_val = q1 - whis*iq
909+
wisk_lo = compress( d >= lo_val, d )
910+
if len(wisk_lo) == 0:
911+
wisk_lo = q1
912+
else:
913+
wisk_lo = min(wisk_lo)
914+
# get fliers - if we are showing them
915+
flier_hi = []
916+
flier_lo = []
917+
flier_hi_x = []
918+
flier_lo_x = []
919+
if len(sym) != 0:
920+
flier_hi = compress( d > wisk_hi, d )
921+
flier_lo = compress( d < wisk_lo, d )
922+
flier_hi_x = ones(flier_hi.shape[0]) * i
923+
flier_lo_x = ones(flier_lo.shape[0]) * i
924+
925+
# get x locations for fliers, whisker, whisker cap and box sides
926+
box_x_min = i - box_width * 0.5
927+
box_x_max = i + box_width * 0.5
928+
929+
wisk_x = ones(2) * i
930+
931+
cap_x_min = i - box_width * 0.25
932+
cap_x_max = i + box_width * 0.25
933+
cap_x = [cap_x_min, cap_x_max]
934+
935+
# get y location for median
936+
med_y = [med, med]
937+
938+
# calculate 'regular' plot
939+
if notch == 0:
940+
# make our box vectors
941+
box_x = [box_x_min, box_x_max, box_x_max, box_x_min, box_x_min ]
942+
box_y = [q1, q1, q3, q3, q1 ]
943+
# make our median line vectors
944+
med_x = [box_x_min, box_x_max]
945+
# calculate 'notch' plot
946+
else:
947+
notch_max = med + 1.57*iq/sqrt(row)
948+
notch_min = med - 1.57*iq/sqrt(row)
949+
if notch_max > q3:
950+
notch_max = q3
951+
if notch_min < q1:
952+
notch_min = q1
953+
# make our notched box vectors
954+
box_x = [box_x_min, box_x_max, box_x_max, cap_x_max, box_x_max, box_x_max, box_x_min, box_x_min, cap_x_min, box_x_min, box_x_min ]
955+
box_y = [q1, q1, notch_min, med, notch_max, q3, q3, notch_max, med, notch_min, q1]
956+
# make our median line vectors
957+
med_x = [cap_x_min, cap_x_max]
958+
med_y = [med, med]
959+
960+
# make a vertical plot . . .
961+
if 1 == vert:
962+
l = self.plot(wisk_x, [q1, wisk_lo], 'b--',
963+
wisk_x, [q3, wisk_hi], 'b--',
964+
cap_x, [wisk_hi, wisk_hi], 'k-',
965+
cap_x, [wisk_lo, wisk_lo], 'k-',
966+
box_x, box_y, 'b-',
967+
med_x, med_y, 'r-',
968+
flier_hi_x, flier_hi, sym,
969+
flier_lo_x, flier_lo, sym )
970+
lines.extend(l)
971+
# or perhaps a horizontal plot
972+
else:
973+
l = self.plot([q1, wisk_lo], wisk_x, 'b--',
974+
[q3, wisk_hi], wisk_x, 'b--',
975+
[wisk_hi, wisk_hi], cap_x, 'k-',
976+
[wisk_lo, wisk_lo], cap_x, 'k-',
977+
box_y, box_x, 'b-',
978+
med_y, med_x, 'r-',
979+
flier_hi, flier_hi_x, sym,
980+
flier_lo, flier_lo_x, sym )
981+
lines.extend(l)
982+
983+
984+
# fix our axes/ticks up a little
985+
if 1 == vert:
986+
self.set_xlim([0.5, 0.5+col])
987+
self.set_xticks(num_plots)
988+
else:
989+
self.set_ylim([0.5, 0.5+col])
990+
self.set_yticks(num_plots)
991+
992+
# reset hold status
993+
self.hold(holdStatus)
994+
995+
return lines
849996

850997
def barh(self, x, y, height=0.8, left=0,
851998
color='b', yerr=None, xerr=None, ecolor='k', capsize=3

lib/matplotlib/font_manager.py

Lines changed: 49 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -64,20 +64,19 @@
6464
# common application, not really useful
6565
"/usr/lib/openoffice/share/fonts/truetype/",
6666
# documented as a good place to install new fonts...
67-
"/usr/share/fonts/",
68-
# okay, now the OS X variants...
69-
"~/Library/Fonts/",
67+
"/usr/share/fonts/"]
68+
69+
OSXFontDirectories = [
7070
"/Library/Fonts/",
7171
"/Network/Library/Fonts/",
72-
"/System/Library/Fonts/",
73-
"System Folder:Fonts:"]
74-
72+
"/System/Library/Fonts/"
73+
]
7574

7675
home = os.environ.get('HOME')
7776
if home is not None:
7877
# user fonts on OSX
7978
path = os.path.join(home, 'Library', 'Fonts')
80-
X11FontDirectories.append(path)
79+
OSXFontDirectories.append(path)
8180

8281
def win32FontDirectory():
8382
"""Return the user-specified font directory for Win32."""
@@ -133,6 +132,35 @@ def win32InstalledFonts(directory=None, fontext='ttf'):
133132
_winreg.CloseKey(local)
134133
return None
135134

135+
def OSXFontDirectory():
136+
"""Return the system font directories for OS X."""
137+
138+
fontpaths = []
139+
def add(arg,directory,files):
140+
fontpaths.append(directory)
141+
for fontdir in OSXFontDirectories:
142+
try:
143+
if os.path.isdir(fontdir):
144+
os.path.walk(fontdir, add, None)
145+
except (IOError, OSError, TypeError, ValueError):
146+
pass
147+
return fontpaths
148+
149+
def OSXInstalledFonts(directory=None, fontext=None):
150+
"""Get list of font files on OS X - ignores font suffix by default"& 10000 quot;"
151+
if directory is None:
152+
directory = OSXFontDirectory()
153+
154+
files = []
155+
for path in directory:
156+
if fontext is None:
157+
files.extend(glob.glob(os.path.join(path,'*')))
158+
else:
159+
files.extend(glob.glob(os.path.join(path, '*.'+fontext)))
160+
files.extend(glob.glob(os.path.join(path, '*.'+fontext.upper())))
161+
return files
162+
163+
136164
def x11FontDirectory():
137165
"""Return the system font directories for X11."""
138166

@@ -176,6 +204,11 @@ def findSystemFonts(fontpaths=None, fontext='ttf'):
176204
fontfiles[f] = 1
177205
else:
178206
fontpaths = x11FontDirectory()
207+
# check for OS X & load its fonts if present
208+
if sys.platform == 'darwin':
209+
for f in OSXInstalledFonts():
210+
fontfiles[f] = 1
211+
179212
elif isinstance(fontpaths, (str, unicode)):
180213
fontpaths = [fontpaths]
181214
for path in fontpaths:
@@ -418,20 +451,20 @@ def createFontDict(fontfiles, fontext='ttf'):
418451
fname = fpath.split('/')[-1]
419452
if seen.has_key(fname): continue
420453
else: seen[fname] = 1
421-
if fontext == 'ttf':
454+
if fontext == 'afm':
422455
try:
423-
font = ft2font.FT2Font(str(fpath))
456+
font = afm.AFM(file(fpath))
424457
except RuntimeError:
425458
warnings.warn("Could not open font file %s"%fpath)
426459
continue
427-
prop = ttfFontProperty(font)
428-
elif fontext == 'afm':
460+
prop = afmFontProperty(font)
461+
else:
429462
try:
430-
font = afm.AFM(file(fpath))
463+
font = ft2font.FT2Font(str(fpath))
431464
except RuntimeError:
432465
warnings.warn("Could not open font file %s"%fpath)
433466
continue
434-
prop = afmFontProperty(font)
467+
prop = ttfFontProperty(font)
435468
add_filename(fontdict, prop, fpath)
436469

437470
# !!!! Default font algorithm needs improvement
@@ -866,9 +899,7 @@ def findfont(self, prop, fontext='ttf'):
866899
verbose.report('findfont returning %s'%fname, 'debug')
867900
return fname
868901

869-
if fontext == 'ttf':
870-
fontdict = self.ttfdict
871-
elif fontext == 'afm':
902+
if fontext == 'afm':
872903
if len(self.afmdict) == 0:
873904
afmpath = os.environ.get('HOME', get_data_path())
874905
afmcache = os.path.join(afmpath, '.afmfont.cache')
@@ -883,6 +914,8 @@ def findfont(self, prop, fontext='ttf'):
883914
pickle.dump(self.afmdict, file(afmcache, 'w'))
884915
verbose.report(cache_message % afmcache)
885916
fontdict = self.afmdict
917+
else:
918+
fontdict = self.ttfdict
886919

887920
name = prop.get_family()[0]
888921
style = prop.get_style()

lib/matplotlib/pylab.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
axis - Set or return the current axis limits
1616
bar - make a bar chart
1717
barh - a horizontal bar chart
18+
boxplot - make a box and whisker plot
1819
cla - clear current axes
1920
clabel - label a contour plot
2021
clf - clear a figure window
@@ -353,6 +354,7 @@ def plotting():
353354
axes - Create a new axes
354355
axis - Set or return the current axis limits
355356
bar - make a bar chart
357+
boxplot - make a box and whiskers chart
356358
cla - clear current axes
357359
clabel - label a contour plot
358360
clf - clear a figure window
@@ -456,7 +458,7 @@ def disconnect(cid):
456458
return get_current_fig_manager().canvas.mpl_disconnect(cid)
457459
disconnect.__doc__ = FigureCanvasBase.mpl_disconnect.__doc__
458460

459-
def get_plot_commands(): return ( 'axes', 'axis', 'bar', 'cla', 'clf',
461+
def get_plot_commands(): return ( 'axes', 'axis', 'bar', 'boxplot', 'cla', 'clf',
460462
'close', 'colorbar', 'cohere', 'csd', 'draw', 'errorbar',
461463
'figlegend', 'figtext', 'figimage', 'figure', 'fill', 'gca',
462464
'gcf', 'gci', 'get', 'gray', 'barh', 'jet', 'hist', 'hold', 'imread',
@@ -1743,6 +1745,27 @@ def bar(*args, **kwargs):
17431745
bar.__doc__ = _shift_string(Axes.bar.__doc__) + """
17441746
Addition kwargs: hold = [True|False] overrides default hold state"""
17451747

1748+
# This function was autogenerated by boilerplate.py. Do not edit as
1749+
# changes will be lost
1750+
def boxplot(*args, **kwargs):
1751+
# allow callers to override the hold state by passing hold=True|False
1752+
b = ishold()
1753+
h = popd(kwargs, 'hold', None)
1754+
if h is not None:
1755+
hold(h)
1756+
try:
1757+
ret = gca().boxplot(*args, **kwargs)
1758+
draw_if_interactive()
1759+
except:
1760+
hold(b)
1761+
raise
1762+
1763+
hold(b)
1764+
return ret
1765+
boxplot.__doc__ = _shift_string(Axes.boxplot.__doc__) + """
1766+
Addition kwargs: hold = [True|False] overrides default hold state"""
1767+
1768+
17461769
# This function was autogenerated by boilerplate.py. Do not edit as
17471770
# changes will be lost
17481771
def barh(*args, **kwargs):

0 commit comments

Comments
 (0)
0