Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit cf2b76a

Browse filesBrowse files
committed
update whats_new, fix line handle, update test
1 parent eca1f25 commit cf2b76a
Copy full SHA for cf2b76a

File tree

Expand file treeCollapse file tree

3 files changed

+43
-31
lines changed
Filter options
Expand file treeCollapse file tree

3 files changed

+43
-31
lines changed

‎doc/users/next_whats_new/boxplot_legend_support.rst

Copy file name to clipboardExpand all lines: doc/users/next_whats_new/boxplot_legend_support.rst
+26-5Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
Legend support for Boxplot
22
~~~~~~~~~~~~~~~~~~~~~~~~~~
33
Boxplots now support a *label* parameter to create legend entries.
4-
Legend labels can be passed as a string to each individual boxplot
5-
or as a list of strings to label multiple boxes in a single
6-
boxplot call.
4+
5+
Legend labels can be passed as a list of strings to label multiple boxes in a single
6+
boxplot call:
77

88

99
.. plot::
1010
:include-source: true
11-
:alt: Example of creating 3 boxplots and assigning legend labels with keywords.
11+
:alt: Example of creating 3 boxplots and assigning legend labels as a sequence.
1212

1313
import matplotlib.pyplot as plt
1414
import numpy as np
@@ -34,4 +34,25 @@ boxplot call.
3434
patch.set_facecolor(color)
3535

3636
ax.legend()
37-
plt.show()
37+
38+
39+
Or as a single string to each individual boxplot. Note that the plot without a
40+
patch artist will get its legend handle from the median line:
41+
42+
.. plot::
43+
:include-source: true
44+
:alt: Example of creating 2 boxplots and assigning each legend label as a string.
45+
46+
fig, ax = plt.subplots()
47+
data_A = np.random.random((100, 3))
48+
data_B = np.random.random((100, 3)) + 0.2
49+
pos = np.arange(3)
50+
51+
bplot2 = ax.boxplot(data_A, positions=pos - 0.2, label='Box A')
52+
bplot3 = ax.boxplot(data_B, positions=pos + 0.2, patch_artist=True, label='Box B')
53+
54+
# fill with colors
55+
for patch in bplot3['boxes']:
56+
patch.set_facecolor('lightblue')
57+
58+
ax.legend()

‎lib/matplotlib/axes/_axes.py

Copy file name to clipboardExpand all lines: lib/matplotlib/axes/_axes.py
+10-16Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4408,22 +4408,16 @@ def do_patch(xs, ys, **kwargs):
44084408

44094409
# Set legend labels
44104410
if label:
4411-
box_or_med = boxes if showbox else medians
4412-
for index, element in enumerate(box_or_med):
4413-
if cbook.is_scalar_or_string(label):
4414-
# If there are multiple boxes, the label
4415-
# should only be applied to the first box.
4416-
if len(box_or_med) > len(label):
4417-
element.set_label(label)
4418-
break
4419-
else:
4420-
element.set_label(label)
4421-
else: # label is a sequence
4422-
if len(box_or_med) == len(label):
4423-
element.set_label(label[index])
4424-
else:
4425-
raise ValueError("There must be an equal number of legend"
4426-
" labels and boxplots.")
4411+
box_or_med = boxes if showbox and patch_artist else medians
4412+
if cbook.is_scalar_or_string(label):
4413+
# assign the label only to the first box
4414+
box_or_med[0].set_label(label)
4415+
else: # label is a sequence
4416+
if len(box_or_med) != len(label):
4417+
raise ValueError("There must be an equal number of legend"
4418+
" labels and boxplots.")
4419+
for artist, lbl in zip(box_or_med, label):
4420+
artist.set_label(lbl)
44274421

44284422
if manage_ticks:
44294423
axis_name = "x" if vert else "y"

‎lib/matplotlib/tests/test_legend.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_legend.py
+7-10Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1457,21 +1457,19 @@ def test_boxplot_legend_labels():
14571457
np.random.seed(19680801)
14581458
data = np.random.random((10, 4))
14591459
fig, axs = plt.subplots(nrows=1, ncols=4)
1460-
legend_labels = ['A', 'B', 'C', 'D']
1460+
legend_labels = ['box A', 'box B', 'box C', 'box D']
14611461

14621462
# Testing legend labels and patch passed to legend.
14631463
bp1 = axs[0].boxplot(data, patch_artist=True, label=legend_labels)
1464-
for i, v in enumerate(bp1['boxes']):
1465-
assert v.get_label() == legend_labels[i]
1464+
assert [v.get_label() for v in bp1['boxes']] == legend_labels
14661465
handles, labels = axs[0].get_legend_handles_labels()
14671466
assert labels == legend_labels
14681467
assert all(isinstance(h, mpl.patches.PathPatch) for h in handles)
14691468

14701469
# Testing legend without `box`.
14711470
bp2 = axs[1].boxplot(data, label=legend_labels, showbox=False)
14721471
# Without a box, The legend entries should be passed from the medians.
1473-
for i, v in enumerate(bp2['medians']):
1474-
assert v.get_label() == legend_labels[i]
1472+
assert [v.get_label() for v in bp2['medians']] == legend_labels
14751473
handles, labels = axs[1].get_legend_handles_labels()
14761474
assert labels == legend_labels
14771475
assert all(isinstance(h, mpl.lines.Line2D) for h in handles)
@@ -1480,8 +1478,7 @@ def test_boxplot_legend_labels():
14801478
with pytest.raises(ValueError, match='There must be an equal number'):
14811479
bp3 = axs[2].boxplot(data, label=legend_labels[:-1])
14821480

1483-
# Of 3 identical boxes, test that only the first box gets a label.
1484-
new_data = np.random.random((100, 3))
1485-
bp4 = axs[3].boxplot(new_data, label='A')
1486-
assert bp4['boxes'][0].get_label() == 'A' and all(x.get_label() != 'A'
1487-
for x in bp4['boxes'][1:])
1481+
# Test that for a string label, only the first box gets a label.
1482+
bp4 = axs[3].boxplot(data, label='box A')
1483+
assert bp4['medians'][0].get_label() == 'box A'
1484+
assert all(x.get_label().startswith("_") for x in bp4['medians'][1:])

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.