Skip to content

Rename boxplot's tick label parameter #27901

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Mar 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions doc/api/next_api_changes/deprecations/27901-TS.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
``boxplot`` tick labels
~~~~~~~~~~~~~~~~~~~~~~~
The parameter *labels* has been renamed to *tick_labels* for clarity and consistency with `~.Axes.bar`.
12 changes: 6 additions & 6 deletions galleries/examples/statistics/boxplot.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,23 +28,23 @@
# Demonstrate how to toggle the display of different elements:

fig, axs = plt.subplots(nrows=2, ncols=3, figsize=(6, 6), sharey=True)
axs[0, 0].boxplot(data, labels=labels)
axs[0, 0].boxplot(data, tick_labels=labels)
axs[0, 0].set_title('Default', fontsize=fs)

axs[0, 1].boxplot(data, labels=labels, showmeans=True)
axs[0, 1].boxplot(data, tick_labels=labels, showmeans=True)
axs[0, 1].set_title('showmeans=True', fontsize=fs)

axs[0, 2].boxplot(data, labels=labels, showmeans=True, meanline=True)
axs[0, 2].boxplot(data, tick_labels=labels, showmeans=True, meanline=True)
axs[0, 2].set_title('showmeans=True,\nmeanline=True', fontsize=fs)

axs[1, 0].boxplot(data, labels=labels, showbox=False, showcaps=False)
axs[1, 0].boxplot(data, tick_labels=labels, showbox=False, showcaps=False)
tufte_title = 'Tufte Style \n(showbox=False,\nshowcaps=False)'
axs[1, 0].set_title(tufte_title, fontsize=fs)

axs[1, 1].boxplot(data, labels=labels, notch=True, bootstrap=10000)
axs[1, 1].boxplot(data, tick_labels=labels, notch=True, bootstrap=10000)
axs[1, 1].set_title('notch=True,\nbootstrap=10000', fontsize=fs)

axs[1, 2].boxplot(data, labels=labels, showfliers=False)
axs[1, 2].boxplot(data, tick_labels=labels, showfliers=False)
axs[1, 2].set_title('showfliers=False', fontsize=fs)

for ax in axs.flat:
Expand Down
2 changes: 1 addition & 1 deletion galleries/examples/statistics/boxplot_color.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

bplot = ax.boxplot(fruit_weights,
patch_artist=True, # fill with color
labels=labels) # will be used to label x-ticks
tick_labels=labels) # will be used to label x-ticks

# fill with colors
for patch, color in zip(bplot['boxes'], colors):
Expand Down
2 changes: 1 addition & 1 deletion galleries/examples/statistics/bxp.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
labels = list('ABCD')

# compute the boxplot stats
stats = cbook.boxplot_stats(data, labels=labels, bootstrap=10000)
stats = cbook.boxplot_stats(data, tick_labels=labels, bootstrap=10000)

# %%
# After we've computed the stats, we can go through and change anything.
Expand Down
17 changes: 12 additions & 5 deletions lib/matplotlib/axes/_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -3789,12 +3789,13 @@ def apply_mask(arrays, mask):
return errorbar_container # (l0, caplines, barcols)

@_preprocess_data()
@_api.rename_parameter("3.9", "labels", "tick_labels")
def boxplot(self, x, notch=None, sym=None, vert=None, whis=None,
positions=None, widths=None, patch_artist=None,
bootstrap=None, usermedians=None, conf_intervals=None,
meanline=None, showmeans=None, showcaps=None,
showbox=None, showfliers=None, boxprops=None,
labels=None, flierprops=None, medianprops=None,
tick_labels=None, flierprops=None, medianprops=None,
meanprops=None, capprops=None, whiskerprops=None,
manage_ticks=True, autorange=False, zorder=None,
capwidths=None):
Expand Down Expand Up @@ -3908,9 +3909,15 @@ def boxplot(self, x, notch=None, sym=None, vert=None, whis=None,
If `False` produces boxes with the Line2D artist. Otherwise,
boxes are drawn with Patch artists.

labels : sequence, optional
Labels for each dataset (one per dataset). These are used for
x-tick labels; *not* for legend entries.
tick_labels : list of str, optional
The tick labels of each boxplot.
Ticks are always placed at the box *positions*. If *tick_labels* is given,
the ticks are labelled accordingly. Otherwise, they keep their numeric
values.

.. versionchanged:: 3.9
Renamed from *labels*, which is deprecated since 3.9
and will be removed in 3.11.

manage_ticks : bool, default: True
If True, the tick locations and labels will be adjusted to match
Expand Down Expand Up @@ -3994,7 +4001,7 @@ def boxplot(self, x, notch=None, sym=None, vert=None, whis=None,
bootstrap = mpl.rcParams['boxplot.bootstrap']

bxpstats = cbook.boxplot_stats(x, whis=whis, bootstrap=bootstrap,
labels=labels, autorange=autorange)
tick_labels=tick_labels, autorange=autorange)
if notch is None:
notch = mpl.rcParams['boxplot.notch']
if vert is None:
Expand Down
2 changes: 1 addition & 1 deletion lib/matplotlib/axes/_axes.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ class Axes(_AxesBase):
showbox: bool | None = ...,
showfliers: bool | None = ...,
boxprops: dict[str, Any] | None = ...,
labels: Sequence[str] | None = ...,
tick_labels: Sequence[str] | None = ...,
flierprops: dict[str, Any] | None = ...,
medianprops: dict[str, Any] | None = ...,
meanprops: dict[str, Any] | None = ...,
Expand Down
19 changes: 12 additions & 7 deletions lib/matplotlib/cbook.py
Original file line number Diff line number Diff line change
Expand Up @@ -1126,7 +1126,8 @@ def _broadcast_with_masks(*args, compress=False):
return inputs


def boxplot_stats(X, whis=1.5, bootstrap=None, labels=None,
@_api.rename_parameter("3.9", "labels", "tick_labels")
def boxplot_stats(X, whis=1.5, bootstrap=None, tick_labels=None,
autorange=False):
r"""
Return a list of dictionaries of statistics used to draw a series of box
Expand Down Expand Up @@ -1161,10 +1162,14 @@ def boxplot_stats(X, whis=1.5, bootstrap=None, labels=None,
Number of times the confidence intervals around the median
should be bootstrapped (percentile method).

labels : array-like, optional
tick_labels : array-like, optional
Labels for each dataset. Length must be compatible with
dimensions of *X*.

.. versionchanged:: 3.9
Renamed from *labels*, which is deprecated since 3.9
and will be removed in 3.11.

autorange : bool, optional (False)
When `True` and the data are distributed such that the 25th and 75th
percentiles are equal, ``whis`` is set to (0, 100) such that the
Expand Down Expand Up @@ -1240,13 +1245,13 @@ def _compute_conf_interval(data, med, iqr, bootstrap):
X = _reshape_2D(X, "X")

ncols = len(X)
if labels is None:
labels = itertools.repeat(None)
elif len(labels) != ncols:
raise ValueError("Dimensions of labels and X must be compatible")
if tick_labels is None:
tick_labels = itertools.repeat(None)
elif len(tick_labels) != ncols:
raise ValueError("Dimensions of tick_labels and X must be compatible")

input_whis = whis
for ii, (x, label) in enumerate(zip(X, labels)):
for ii, (x, label) in enumerate(zip(X, tick_labels)):

# empty dict
stats = {}
Expand Down
2 changes: 1 addition & 1 deletion lib/matplotlib/cbook.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ def boxplot_stats(
X: ArrayLike,
whis: float | tuple[float, float] = ...,
bootstrap: int | None = ...,
labels: ArrayLike | None = ...,
tick_labels: ArrayLike | None = ...,
autorange: bool = ...,
) -> list[dict[str, Any]]: ...

Expand Down
4 changes: 2 additions & 2 deletions lib/matplotlib/pyplot.py
Original file line number Diff line number Diff line change
Expand Up @@ -2852,7 +2852,7 @@ def boxplot(
showbox: bool | None = None,
showfliers: bool | None = None,
boxprops: dict[str, Any] | None = None,
labels: Sequence[str] | None = None,
tick_labels: Sequence[str] | None = None,
flierprops: dict[str, Any] | None = None,
medianprops: dict[str, Any] | None = None,
meanprops: dict[str, Any] | None = None,
Expand Down Expand Up @@ -2883,7 +2883,7 @@ def boxplot(
showbox=showbox,
showfliers=showfliers,
boxprops=boxprops,
labels=labels,
tick_labels=tick_labels,
flierprops=flierprops,
medianprops=medianprops,
meanprops=meanprops,
Expand Down
18 changes: 18 additions & 0 deletions lib/matplotlib/tests/test_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -8966,3 +8966,21 @@ def test_axes_clear_behavior(fig_ref, fig_test, which):

ax_ref.grid(True)
ax_test.grid(True)


def test_boxplot_tick_labels():
# Test the renamed `tick_labels` parameter.
# Test for deprecation of old name `labels`.
np.random.seed(19680801)
data = np.random.random((10, 3))

fig, axs = plt.subplots(nrows=1, ncols=2, sharey=True)
# Should get deprecation warning for `labels`
with pytest.warns(mpl.MatplotlibDeprecationWarning,
match='has been renamed \'tick_labels\''):
axs[0].boxplot(data, labels=['A', 'B', 'C'])
assert [l.get_text() for l in axs[0].get_xticklabels()] == ['A', 'B', 'C']

# Test the new tick_labels parameter
axs[1].boxplot(data, tick_labels=['A', 'B', 'C'])
assert [l.get_text() for l in axs[1].get_xticklabels()] == ['A', 'B', 'C']
4 changes: 2 additions & 2 deletions lib/matplotlib/tests/test_cbook.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ def test_results_whiskers_percentiles(self):

def test_results_withlabels(self):
labels = ['Test1', 2, 'Aardvark', 4]
results = cbook.boxplot_stats(self.data, labels=labels)
results = cbook.boxplot_stats(self.data, tick_labels=labels)
for lab, res in zip(labels, results):
assert res['label'] == lab

Expand All @@ -156,7 +156,7 @@ def test_results_withlabels(self):
def test_label_error(self):
labels = [1, 2]
with pytest.raises(ValueError):
cbook.boxplot_stats(self.data, labels=labels)
cbook.boxplot_stats(self.data, tick_labels=labels)

def test_bad_dims(self):
data = np.random.normal(size=(34, 34, 34))
Expand Down
15 changes: 0 additions & 15 deletions lib/matplotlib/tests/test_legend.py
Original file line number Diff line number Diff line change
Expand Up @@ -1435,18 +1435,3 @@ def test_legend_text():
leg_bboxes.append(
leg.get_window_extent().transformed(ax.transAxes.inverted()))
assert_allclose(leg_bboxes[1].bounds, leg_bboxes[0].bounds)


def test_boxplot_labels():
# Test that boxplot(..., labels=) sets the tick labels but not legend entries
# This is not consistent with other plot types but is the current behavior.
fig, ax = plt.subplots()
np.random.seed(19680801)
data = np.random.random((10, 3))
bp = ax.boxplot(data, labels=['A', 'B', 'C'])
# Check that labels set the tick labels ...
assert [l.get_text() for l in ax.get_xticklabels()] == ['A', 'B', 'C']
# ... but not legend entries
handles, labels = ax.get_legend_handles_labels()
assert len(handles) == 0
assert len(labels) == 0