Skip to content

Commit 2932deb

Browse files
committed
Add patch_artist kwarg to boxplot
svn path=/trunk/matplotlib/; revision=8034
1 parent 70149d6 commit 2932deb

File tree

4 files changed

+54
-26
lines changed

4 files changed

+54
-26
lines changed

CHANGELOG

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
2009-12-14 Add patch_artist kwarg to boxplot, but keep old default.
2+
Convert boxplot_demo2.py to use the new patch_artist. - ADS
3+
14
2009-12-06 axes_grid: reimplemented AxisArtist with FloatingAxes support.
25
Added new examples. - JJL
36

examples/pylab_examples/boxplot_demo2.py

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@
4242
ax1 = fig.add_subplot(111)
4343
plt.subplots_adjust(left=0.075, right=0.95, top=0.9, bottom=0.25)
4444

45-
bp = plt.boxplot(data, notch=0, sym='+', vert=1, whis=1.5)
46-
plt.setp(bp['boxes'], color='black')
45+
bp = plt.boxplot(data, notch=0, sym='+', vert=1, whis=1.5, patch_artist=True)
46+
plt.setp(bp['boxes'], edgecolor='black')
4747
plt.setp(bp['whiskers'], color='black')
4848
plt.setp(bp['fliers'], color='red', marker='+')
4949

@@ -64,25 +64,12 @@
6464
medians = range(numBoxes)
6565
for i in range(numBoxes):
6666
box = bp['boxes'][i]
67-
boxX = []
68-
boxY = []
69-
for j in range(5):
70-
boxX.append(box.get_xdata()[j])
71-
boxY.append(box.get_ydata()[j])
72-
boxCoords = zip(boxX,boxY)
73-
# Alternate between Dark Khaki and Royal Blue
7467
k = i % 2
75-
boxPolygon = Polygon(boxCoords, facecolor=boxColors[k])
76-
ax1.add_patch(boxPolygon)
77-
# Now draw the median lines back over what we just filled in
68+
# Set the box colors
69+
box.set_facecolor(boxColors[k])
70+
# Now get the medians
7871
med = bp['medians'][i]
79-
medianX = []
80-
medianY = []
81-
for j in range(2):
82-
medianX.append(med.get_xdata()[j])
83-
medianY.append(med.get_ydata()[j])
84-
plt.plot(medianX, medianY, 'k')
85-
medians[i] = medianY[0]
72+
medians[i] = med.get_ydata()[0]
8673
# Finally, overplot the sample averages, with horixzontal alignment
8774
# in the center of each box
8875
plt.plot([np.average(med.get_xdata())], [np.average(data[i])],

lib/matplotlib/axes.py

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import matplotlib.legend as mlegend
2222
import matplotlib.lines as mlines
2323
import matplotlib.mlab as mlab
24+
import matplotlib.path as mpath
2425
import matplotlib.patches as mpatches
2526
import matplotlib.spines as mspines
2627
import matplotlib.quiver as mquiver
@@ -4892,19 +4893,21 @@ def xywhere(xs, ys, mask):
48924893
return (l0, caplines, barcols)
48934894

48944895
def boxplot(self, x, notch=0, sym='b+', vert=1, whis=1.5,
4895-
positions=None, widths=None):
4896+
positions=None, widths=None, patch_artist=False):
48964897
"""
48974898
call signature::
48984899
48994900
boxplot(x, notch=0, sym='+', vert=1, whis=1.5,
4900-
positions=None, widths=None)
4901+
positions=None, widths=None, patch_artist=False)
49014902
49024903
Make a box and whisker plot for each column of *x* or each
49034904
vector in sequence *x*. The box extends from the lower to
49044905
upper quartile values of the data, with a line at the median.
49054906
The whiskers extend from the box to show the range of the
49064907
data. Flier points are those past the end of the whiskers.
49074908
4909+
*x* is an array or a sequence of vectors.
4910+
49084911
- *notch* = 0 (default) produces a rectangular box plot.
49094912
- *notch* = 1 will produce a notched box plot
49104913
@@ -4927,7 +4930,8 @@ def boxplot(self, x, notch=0, sym='b+', vert=1, whis=1.5,
49274930
each box. The default is 0.5, or ``0.15*(distance between extreme
49284931
positions)`` if that is smaller.
49294932
4930-
*x* is an array or a sequence of vectors.
4933+
- *patch_artist* = False (default) produces boxes with the Line2D artist
4934+
- *patch_artist* = True produces boxes with the Patch artist
49314935
49324936
Returns a dictionary mapping each component of the boxplot
49334937
to a list of the :class:`matplotlib.lines.Line2D`
@@ -5045,23 +5049,55 @@ def boxplot(self, x, notch=0, sym='b+', vert=1, whis=1.5,
50455049
med_x = [cap_x_min, cap_x_max]
50465050
med_y = [med, med]
50475051

5052+
def to_vc(xs,ys):
5053+
# convert arguments to verts and codes
5054+
verts = []
5055+
#codes = []
5056+
for xi,yi in zip(xs,ys):
5057+
verts.append( (xi,yi) )
5058+
verts.append( (0,0) ) # ignored
5059+
codes = [mpath.Path.MOVETO] + \
5060+
[mpath.Path.LINETO]*(len(verts)-2) + \
5061+
[mpath.Path.CLOSEPOLY]
5062+
return verts,codes
5063+
5064+
def patch_list(xs,ys):
5065+
verts,codes = to_vc(xs,ys)
5066+
path = mpath.Path( verts, codes )
5067+
patch = mpatches.PathPatch(path)
5068+
self.add_artist(patch)
5069+
return [patch]
5070+
50485071
# vertical or horizontal plot?
50495072
if vert:
50505073
def doplot(*args):
50515074
return self.plot(*args)
5075+
def dopatch(xs,ys):
5076+
return patch_list(xs,ys)
50525077
else:
50535078
def doplot(*args):
50545079
shuffled = []
50555080
for i in xrange(0, len(args), 3):
50565081
shuffled.extend([args[i+1], args[i], args[i+2]])
50575082
return self.plot(*shuffled)
5083+
def dopatch(xs,ys):
5084+
xs,ys = ys,xs # flip X, Y
5085+
return patch_list(xs,ys)
5086+
5087+
if patch_artist:
5088+
median_color = 'k'
5089+
else:
5090+
median_color = 'r'
50585091

50595092
whiskers.extend(doplot(wisk_x, [q1, wisk_lo], 'b--',
50605093
wisk_x, [q3, wisk_hi], 'b--'))
50615094
caps.extend(doplot(cap_x, [wisk_hi, wisk_hi], 'k-',
50625095
cap_x, [wisk_lo, wisk_lo], 'k-'))
5063-
boxes.extend(doplot(box_x, box_y, 'b-'))
5064-
medians.extend(doplot(med_x, med_y, 'r-'))
5096+
if patch_artist:
5097+
boxes.extend(dopatch(box_x, box_y))
5098+
else:
5099+
boxes.extend(doplot(box_x, box_y, 'b-'))
5100+
medians.extend(doplot(med_x, med_y, median_color+'-'))
50655101
fliers.extend(doplot(flier_hi_x, flier_hi, sym,
50665102
flier_lo_x, flier_lo, sym))
50675103

lib/matplotlib/pyplot.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1767,15 +1767,17 @@ def broken_barh(xranges, yrange, hold=None, **kwargs):
17671767
# This function was autogenerated by boilerplate.py. Do not edit as
17681768
# changes will be lost
17691769
@autogen_docstring(Axes.boxplot)
1770-
def boxplot(x, notch=0, sym='b+', vert=1, whis=1.5, positions=None, widths=None, hold=None):
1770+
def boxplot(x, notch=0, sym='b+', vert=1, whis=1.5, positions=None, widths=None,
1771+
hold=None, patch_artist=False):
17711772
ax = gca()
17721773
# allow callers to override the hold state by passing hold=True|False
17731774
washold = ax.ishold()
17741775

17751776
if hold is not None:
17761777
ax.hold(hold)
17771778
try:
1778-
ret = ax.boxplot(x, notch, sym, vert, whis, positions, widths)
1779+
ret = ax.boxplot(x, notch, sym, vert, whis, positions, widths,
1780+
patch_artist=patch_artist)
17791781
draw_if_interactive()
17801782
finally:
17811783
ax.hold(washold)

0 commit comments

Comments
 (0)