Skip to content

Commit b079233

Browse files
authored
Merge pull request #14360 from anntzer/boxplot-whis
Deprecate `boxplot(..., whis="range")`.
2 parents 1636407 + a49cdbe commit b079233

File tree

7 files changed

+64
-39
lines changed

7 files changed

+64
-39
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Deprecations
2+
````````````
3+
4+
Setting the ``whis`` parameter of `.Axes.boxplot` and `.cbook.boxplot_stats` to
5+
"range" to mean "the whole data range" is deprecated; set it to (0, 100) (which
6+
gets interpreted as percentiles) to achieve the same effect.

examples/statistics/boxplot.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@
7474
axs[0, 1].boxplot(data, flierprops=flierprops, medianprops=medianprops)
7575
axs[0, 1].set_title('Custom medianprops\nand flierprops', fontsize=fs)
7676

77-
axs[0, 2].boxplot(data, whis='range')
78-
axs[0, 2].set_title('whis="range"', fontsize=fs)
77+
axs[0, 2].boxplot(data, whis=(0, 100))
78+
axs[0, 2].set_title('whis=(0, 100)', fontsize=fs)
7979

8080
axs[1, 0].boxplot(data, meanprops=meanpointprops, meanline=False,
8181
showmeans=True)

lib/matplotlib/axes/_axes.py

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3502,19 +3502,26 @@ def boxplot(self, x, notch=None, sym=None, vert=None, whis=None,
35023502
If `True` (default), makes the boxes vertical. If `False`,
35033503
everything is drawn horizontally.
35043504
3505-
whis : float, sequence, or string (default = 1.5)
3506-
As a float, determines the reach of the whiskers beyond the
3507-
first and third quartiles. In other words, where IQR is the
3508-
interquartile range (`Q3-Q1`), the upper whisker will extend to
3509-
last datum less than `Q3 + whis*IQR`). Similarly, the lower whisker
3510-
will extend to the first datum greater than `Q1 - whis*IQR`.
3511-
Beyond the whiskers, data
3512-
are considered outliers and are plotted as individual
3513-
points. Alternatively, set
3514-
this to an ascending sequence of percentile (e.g., [5, 95])
3515-
to set the whiskers at specific percentiles of the data.
3516-
Finally, ``whis`` can be the string ``'range'`` to force the
3517-
whiskers to the min and max of the data.
3505+
whis : float or (float, float) (default = 1.5)
3506+
The position of the whiskers.
3507+
3508+
If a float, the lower whisker is at the lowest datum above
3509+
``Q1 - whis*(Q3-Q1)``, and the upper whisker at the highest datum
3510+
below ``Q3 + whis*(Q3-Q1)``, where Q1 and Q3 are the first and
3511+
third quartiles. The default value of ``whis = 1.5`` corresponds
3512+
to Tukey's original definition of boxplots.
3513+
3514+
If a pair of floats, they indicate the percentiles at which to
3515+
draw the whiskers (e.g., (5, 95)). In particular, setting this to
3516+
(0, 100) results in whiskers covering the whole range of the data.
3517+
"range" is a deprecated synonym for (0, 100).
3518+
3519+
In the edge case where ``Q1 == Q3``, *whis* is automatically set
3520+
to (0, 100) (cover the whole range of the data) if *autorange* is
3521+
True.
3522+
3523+
Beyond the whiskers, data are considered outliers and are plotted
3524+
as individual points.
35183525
35193526
bootstrap : int, optional
35203527
Specifies whether to bootstrap the confidence intervals
@@ -3567,7 +3574,7 @@ def boxplot(self, x, notch=None, sym=None, vert=None, whis=None,
35673574
35683575
autorange : bool, optional (False)
35693576
When `True` and the data are distributed such that the 25th and
3570-
75th percentiles are equal, ``whis`` is set to ``'range'`` such
3577+
75th percentiles are equal, ``whis`` is set to (0, 100) such
35713578
that the whisker ends are at the minimum and maximum of the data.
35723579
35733580
meanline : bool, optional (False)

lib/matplotlib/cbook/__init__.py

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,20 +1039,25 @@ def boxplot_stats(X, whis=1.5, bootstrap=None, labels=None,
10391039
Data that will be represented in the boxplots. Should have 2 or
10401040
fewer dimensions.
10411041
1042-
whis : float, string, or sequence (default = 1.5)
1043-
As a float, determines the reach of the whiskers beyond the
1044-
first and third quartiles. In other words, where IQR is the
1045-
interquartile range (`Q3-Q1`), the upper whisker will extend to last
1046-
datum less than `Q3 + whis*IQR`. Similarly, the lower whisker will
1047-
extend to the first datum greater than `Q1 - whis*IQR`.
1048-
Beyond the whiskers, data are considered outliers
1049-
and are plotted as individual points. This can be set to an
1050-
ascending sequence of percentiles (e.g., [5, 95]) to set the
1051-
whiskers at specific percentiles of the data. Finally, `whis`
1052-
can be the string ``'range'`` to force the whiskers to the
1053-
minimum and maximum of the data. In the edge case that the 25th
1054-
and 75th percentiles are equivalent, `whis` can be automatically
1055-
set to ``'range'`` via the `autorange` option.
1042+
whis : float or (float, float) (default = 1.5)
1043+
The position of the whiskers.
1044+
1045+
If a float, the lower whisker is at the lowest datum above
1046+
``Q1 - whis*(Q3-Q1)``, and the upper whisker at the highest datum below
1047+
``Q3 + whis*(Q3-Q1)``, where Q1 and Q3 are the first and third
1048+
quartiles. The default value of ``whis = 1.5`` corresponds to Tukey's
1049+
original definition of boxplots.
1050+
1051+
If a pair of floats, they indicate the percentiles at which to draw the
1052+
whiskers (e.g., (5, 95)). In particular, setting this to (0, 100)
1053+
results in whiskers covering the whole range of the data. "range" is
1054+
a deprecated synonym for (0, 100).
1055+
1056+
In the edge case where ``Q1 == Q3``, *whis* is automatically set to
1057+
(0, 100) (cover the whole range of the data) if *autorange* is True.
1058+
1059+
Beyond the whiskers, data are considered outliers and are plotted as
1060+
individual points.
10561061
10571062
bootstrap : int, optional
10581063
Number of times the confidence intervals around the median
@@ -1064,7 +1069,7 @@ def boxplot_stats(X, whis=1.5, bootstrap=None, labels=None,
10641069
10651070
autorange : bool, optional (False)
10661071
When `True` and the data are distributed such that the 25th and 75th
1067-
percentiles are equal, ``whis`` is set to ``'range'`` such that the
1072+
percentiles are equal, ``whis`` is set to (0, 100) such that the
10681073
whisker ends are at the minimum and maximum of the data.
10691074
10701075
Returns
@@ -1182,7 +1187,7 @@ def _compute_conf_interval(data, med, iqr, bootstrap):
11821187
# interquartile range
11831188
stats['iqr'] = q3 - q1
11841189
if stats['iqr'] == 0 and autorange:
1185-
whis = 'range'
1190+
whis = (0, 100)
11861191

11871192
# conf. interval around median
11881193
stats['cilo'], stats['cihi'] = _compute_conf_interval(
@@ -1195,14 +1200,17 @@ def _compute_conf_interval(data, med, iqr, bootstrap):
11951200
loval = q1 - whis * stats['iqr']
11961201
hival = q3 + whis * stats['iqr']
11971202
elif whis in ['range', 'limit', 'limits', 'min/max']:
1203+
warn_deprecated(
1204+
"3.2", message=f"Setting whis to {whis!r} is deprecated "
1205+
"since %(since)s and support for it will be removed "
1206+
"%(removal)s; set it to [0, 100] to achieve the same "
1207+
"effect.")
11981208
loval = np.min(x)
11991209
hival = np.max(x)
12001210
else:
1201-
raise ValueError('whis must be a float, valid string, or list '
1202-
'of percentiles')
1211+
raise ValueError('whis must be a float or list of percentiles')
12031212
else:
1204-
loval = np.percentile(x, whis[0])
1205-
hival = np.percentile(x, whis[1])
1213+
loval, hival = np.percentile(x, whis)
12061214

12071215
# get high extreme
12081216
wiskhi = x[x <= hival]

lib/matplotlib/rcsetup.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,10 @@ def validate_verbose(s):
503503

504504
def validate_whiskers(s):
505505
if s == 'range':
506+
cbook.warn_deprecated(
507+
"3.2", message="Support for setting the boxplot.whiskers rcParam "
508+
"to 'range' is deprecated since %(since)s and will be removed "
509+
"%(removal)s; set it to 0, 100 instead.")
506510
return 'range'
507511
else:
508512
try:

lib/matplotlib/tests/test_axes.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2182,7 +2182,7 @@ def test_bxp_baseline():
21822182
savefig_kwarg={'dpi': 40},
21832183
style='default')
21842184
def test_bxp_rangewhis():
2185-
_bxp_test_helper(stats_kwargs=dict(whis='range'))
2185+
_bxp_test_helper(stats_kwargs=dict(whis=[0, 100]))
21862186

21872187

21882188
@image_comparison(['bxp_precentilewhis.png'],
@@ -2500,7 +2500,7 @@ def test_boxplot_rc_parameters():
25002500

25012501
rc_axis1 = {
25022502
'boxplot.vertical': False,
2503-
'boxplot.whiskers': 'range',
2503+
'boxplot.whiskers': [0, 100],
25042504
'boxplot.patchartist': True,
25052505
}
25062506

lib/matplotlib/tests/test_cbook.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ def test_results_whiskers_float(self):
147147
assert_array_almost_equal(res[key], value)
148148

149149
def test_results_whiskers_range(self):
150-
results = cbook.boxplot_stats(self.data, whis='range')
150+
results = cbook.boxplot_stats(self.data, whis=[0, 100])
151151
res = results[0]
152152
for key, value in self.known_res_range.items():
153153
assert_array_almost_equal(res[key], value)

0 commit comments

Comments
 (0)