Skip to content

Commit a1cfa29

Browse files
committed
Merge pull request matplotlib#3165 from tacaswell/bug-restore-boxplot-defaults
Bug restore boxplot defaults
2 parents 3b4f958 + 01b7b77 commit a1cfa29

13 files changed

+277
-190
lines changed

Diff for: lib/matplotlib/axes/_axes.py

+81-38
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import matplotlib.transforms as mtrans
4040
from matplotlib.container import BarContainer, ErrorbarContainer, StemContainer
4141
from matplotlib.axes._base import _AxesBase
42+
from matplotlib.axes._base import _process_plot_format
4243

4344
iterable = cbook.iterable
4445
is_string_like = cbook.is_string_like
@@ -2887,18 +2888,19 @@ def boxplot(self, x, notch=False, sym='b+', vert=True, whis=1.5,
28872888
meanline=False, showmeans=False, showcaps=True,
28882889
showbox=True, showfliers=True, boxprops=None, labels=None,
28892890
flierprops=None, medianprops=None, meanprops=None,
2890-
manage_xticks=True):
2891+
capprops=None, whiskerprops=None, manage_xticks=True):
28912892
"""
28922893
Make a box and whisker plot.
28932894
28942895
Call signature::
28952896
2896-
boxplot(x, notch=False, sym='b+', vert=True, whis=1.5,
2897+
boxplot(self, x, notch=False, sym='b+', vert=True, whis=1.5,
28972898
positions=None, widths=None, patch_artist=False,
28982899
bootstrap=None, usermedians=None, conf_intervals=None,
28992900
meanline=False, showmeans=False, showcaps=True,
29002901
showbox=True, showfliers=True, boxprops=None, labels=None,
2901-
flierprops=None, medianprops=None, meanprops=None)
2902+
flierprops=None, medianprops=None, meanprops=None,
2903+
capprops=None, whiskerprops=None, manage_xticks=True):
29022904
29032905
Make a box and whisker plot for each column of *x* or each
29042906
vector in sequence *x*. The box extends from the lower to
@@ -2994,6 +2996,12 @@ def boxplot(self, x, notch=False, sym='b+', vert=True, whis=1.5,
29942996
boxprops : dict or None (default)
29952997
If provided, will set the plotting style of the boxes
29962998
2999+
whiskerprops : dict or None (default)
3000+
If provided, will set the plotting style of the whiskers
3001+
3002+
capprops : dict or None (default)
3003+
If provided, will set the plotting style of the caps
3004+
29973005
flierprops : dict or None (default)
29983006
If provided, will set the plotting style of the fliers
29993007
@@ -3034,14 +3042,15 @@ def boxplot(self, x, notch=False, sym='b+', vert=True, whis=1.5,
30343042
"""
30353043
bxpstats = cbook.boxplot_stats(x, whis=whis, bootstrap=bootstrap,
30363044
labels=labels)
3037-
if sym == 'b+' and flierprops is None:
3038-
flierprops = dict(linestyle='none', marker='+',
3039-
markeredgecolor='blue')
3045+
if flierprops is None:
3046+
flierprops = dict(sym=sym)
3047+
else:
3048+
flierprops['sym'] = sym
30403049

30413050
# replace medians if necessary:
30423051
if usermedians is not None:
30433052
if (len(np.ravel(usermedians)) != len(bxpstats) or
3044-
np.shape(usermedians)[0] != len(bxpstats)):
3053+
np.shape(usermedians)[0] != len(bxpstats)):
30453054
medmsg = 'usermedians length not compatible with x'
30463055
raise ValueError(medmsg)
30473056
else:
@@ -3073,24 +3082,27 @@ def boxplot(self, x, notch=False, sym='b+', vert=True, whis=1.5,
30733082
boxprops=boxprops, flierprops=flierprops,
30743083
medianprops=medianprops, meanprops=meanprops,
30753084
meanline=meanline, showfliers=showfliers,
3085+
capprops=capprops, whiskerprops=whiskerprops,
30763086
manage_xticks=manage_xticks)
30773087
return artists
30783088

30793089
def bxp(self, bxpstats, positions=None, widths=None, vert=True,
30803090
patch_artist=False, shownotches=False, showmeans=False,
30813091
showcaps=True, showbox=True, showfliers=True,
3082-
boxprops=None, flierprops=None, medianprops=None,
3083-
meanprops=None, meanline=False, manage_xticks=True):
3092+
boxprops=None, whiskerprops=None, flierprops=None,
3093+
medianprops=None, capprops=None, meanprops=None,
3094+
meanline=False, manage_xticks=True):
30843095
"""
30853096
Drawing function for box and whisker plots.
30863097
30873098
Call signature::
30883099
3089-
bxp(bxpstats, positions=None, widths=None, vert=True,
3100+
bxp(self, bxpstats, positions=None, widths=None, vert=True,
30903101
patch_artist=False, shownotches=False, showmeans=False,
30913102
showcaps=True, showbox=True, showfliers=True,
3092-
boxprops=None, flierprops=None, medianprops=None,
3093-
meanprops=None, meanline=False, manage_xticks=True)
3103+
boxprops=None, whiskerprops=None, flierprops=None,
3104+
medianprops=None, capprops=None, meanprops=None,
3105+
meanline=False, manage_xticks=True):
30943106
30953107
Make a box and whisker plot for each column of *x* or each
30963108
vector in sequence *x*. The box extends from the lower to
@@ -3136,14 +3148,14 @@ def bxp(self, bxpstats, positions=None, widths=None, vert=True,
31363148
If True produces boxes with the Patch artist
31373149
31383150
shownotches : bool, default = False
3139-
If False (default), produces a rectangular box plot.
3140-
If True, will produce a notched box plot
3151+
If False (default), produces a rectangular box plot.
3152+
If True, will produce a notched box plot
31413153
31423154
showmeans : bool, default = False
31433155
If True, will toggle one the rendering of the means
31443156
31453157
showcaps : bool, default = True
3146-
If True, will toggle one the rendering of the caps
3158+
If True will toggle one the rendering of the caps
31473159
31483160
showbox : bool, default = True
31493161
If True, will toggle one the rendering of box
@@ -3154,8 +3166,14 @@ def bxp(self, bxpstats, positions=None, widths=None, vert=True,
31543166
boxprops : dict or None (default)
31553167
If provided, will set the plotting style of the boxes
31563168
3169+
whiskerprops : dict or None (default)
3170+
If provided, will set the plotting style of the whiskers
3171+
3172+
capprops : dict or None (default)
3173+
If provided, will set the plotting style of the caps
3174+
31573175
flierprops : dict or None (default)
3158-
If provided, will set the plotting style of the fliers
3176+
If provided will set the plotting style of the fliers
31593177
31603178
medianprops : dict or None (default)
31613179
If provided, will set the plotting style of the medians
@@ -3219,37 +3237,58 @@ def bxp(self, bxpstats, positions=None, widths=None, vert=True,
32193237
final_boxprops = dict(linestyle='solid', edgecolor='black',
32203238
facecolor='white', linewidth=1)
32213239
else:
3222-
final_boxprops = dict(linestyle='-', color='black', linewidth=1)
3240+
final_boxprops = dict(linestyle='-', color='blue')
32233241

32243242
if boxprops is not None:
32253243
final_boxprops.update(boxprops)
32263244

32273245
# other (cap, whisker) properties
3228-
if patch_artist:
3229-
otherprops = dict(
3230-
linestyle=linestyle_map[final_boxprops['linestyle']],
3231-
color=final_boxprops['edgecolor'],
3232-
linewidth=final_boxprops.get('linewidth', 1)
3233-
)
3234-
else:
3235-
otherprops = dict(linestyle=final_boxprops['linestyle'],
3236-
color=final_boxprops['color'],
3237-
linewidth=final_boxprops.get('linewidth', 1))
3246+
final_whiskerprops = dict(
3247+
linestyle='--',
3248+
color='blue',
3249+
)
32383250

3239-
# flier (outlier) properties
3251+
final_capprops = dict(
3252+
linestyle='-',
3253+
color='black',
3254+
)
3255+
3256+
if capprops is not None:
3257+
final_capprops.update(capprops)
3258+
3259+
if whiskerprops is not None:
3260+
final_whiskerprops.update(whiskerprops)
3261+
3262+
# set up the default flier properties
32403263
final_flierprops = dict(linestyle='none', marker='+',
3241-
markeredgecolor='blue')
3264+
markeredgecolor='b',
3265+
markerfacecolor='none')
3266+
# flier (outlier) properties
32423267
if flierprops is not None:
3268+
sym = flierprops.pop('sym', None)
3269+
3270+
# watch inverted logic, checks for non-default
3271+
# value of `sym`
3272+
if not (sym == '' or (sym is None)):
3273+
# process the symbol string
3274+
# discarded linestyle
3275+
_, marker, color = _process_plot_format(sym)
3276+
flierprops['marker'] = marker
3277+
flierprops['color'] = color
3278+
# assume that if color is passed in the user want
3279+
# filled symbol
3280+
flierprops['markeredgecolor'] = color
3281+
flierprops['markerfacecolor'] = color
32433282
final_flierprops.update(flierprops)
32443283

32453284
# median line properties
3246-
final_medianprops = dict(linestyle='-', color='blue')
3285+
final_medianprops = dict(linestyle='-', color='red')
32473286
if medianprops is not None:
32483287
final_medianprops.update(medianprops)
32493288

32503289
# mean (line or point) properties
32513290
if meanline:
3252-
final_meanprops = dict(linestyle='--', color='red')
3291+
final_meanprops = dict(linestyle='--', color='black')
32533292
else:
32543293
final_meanprops = dict(linestyle='none', markerfacecolor='red',
32553294
marker='s')
@@ -3317,11 +3356,9 @@ def dopatch(xs, ys, **kwargs):
33173356
if not self._hold:
33183357
self.cla()
33193358
holdStatus = self._hold
3320-
33213359
for pos, width, stats in zip(positions, widths, bxpstats):
33223360
# try to find a new label
33233361
datalabels.append(stats.get('label', pos))
3324-
33253362
# fliers coords
33263363
flier_x = np.ones(len(stats['fliers'])) * pos
33273364
flier_y = stats['fliers']
@@ -3369,13 +3406,17 @@ def dopatch(xs, ys, **kwargs):
33693406
boxes.extend(doplot(box_x, box_y, **final_boxprops))
33703407

33713408
# draw the whiskers
3372-
whiskers.extend(doplot(whisker_x, whiskerlo_y, **otherprops))
3373-
whiskers.extend(doplot(whisker_x, whiskerhi_y, **otherprops))
3409+
whiskers.extend(doplot(
3410+
whisker_x, whiskerlo_y, **final_whiskerprops
3411+
))
3412+
whiskers.extend(doplot(
3413+
whisker_x, whiskerhi_y, **final_whiskerprops
3414+
))
33743415

33753416
# maybe draw the caps:
33763417
if showcaps:
3377-
caps.extend(doplot(cap_x, cap_lo, **otherprops))
3378-
caps.extend(doplot(cap_x, cap_hi, **otherprops))
3418+
caps.extend(doplot(cap_x, cap_lo, **final_capprops))
3419+
caps.extend(doplot(cap_x, cap_hi, **final_capprops))
33793420

33803421
# draw the medians
33813422
medians.extend(doplot(med_x, med_y, **final_medianprops))
@@ -3394,7 +3435,9 @@ def dopatch(xs, ys, **kwargs):
33943435

33953436
# maybe draw the fliers
33963437
if showfliers:
3397-
fliers.extend(doplot(flier_x, flier_y, **final_flierprops))
3438+
fliers.extend(doplot(
3439+
flier_x, flier_y, **final_flierprops
3440+
))
33983441

33993442
# fix our axes/ticks up a little
34003443
if vert:

Diff for: lib/matplotlib/cbook.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1948,7 +1948,7 @@ def _compute_conf_interval(data, med, iqr, bootstrap):
19481948

19491949
ncols = len(X)
19501950
if labels is None:
1951-
labels = [str(i) for i in range(ncols)]
1951+
labels = [str(i) for i in range(1, ncols+1)]
19521952
elif len(labels) != ncols:
19531953
raise ValueError("Dimensions of labels and X must be compatible")
19541954

28 Bytes
Binary file not shown.
-147 Bytes
Loading

0 commit comments

Comments
 (0)