Skip to content

Commit a382045

Browse files
authored
Merge pull request matplotlib#27711 from saranti/boxlegend
Fix boxplot legend entries part 2
2 parents 41d4149 + 6ef9cce commit a382045

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed

lib/matplotlib/axes/_axes.py

+7
Original file line numberDiff line numberDiff line change
@@ -4004,6 +4004,9 @@ def boxplot(self, x, notch=None, sym=None, vert=None, whis=None,
40044004
if 'color' in boxprops:
40054005
boxprops['edgecolor'] = boxprops.pop('color')
40064006

4007+
if labels:
4008+
boxprops['label'] = labels
4009+
40074010
# if non-default sym value, put it into the flier dictionary
40084011
# the logic for providing the default symbol ('b+') now lives
40094012
# in bxp in the initial value of flierkw
@@ -4316,13 +4319,16 @@ def do_patch(xs, ys, **kwargs):
43164319
do_box = do_patch if patch_artist else do_plot
43174320
boxes.append(do_box(box_x, box_y, **box_kw))
43184321
# draw the whiskers
4322+
whisker_kw.setdefault('label', '_nolegend_')
43194323
whiskers.append(do_plot(whis_x, whislo_y, **whisker_kw))
43204324
whiskers.append(do_plot(whis_x, whishi_y, **whisker_kw))
43214325
# maybe draw the caps
43224326
if showcaps:
4327+
cap_kw.setdefault('label', '_nolegend_')
43234328
caps.append(do_plot(cap_x, cap_lo, **cap_kw))
43244329
caps.append(do_plot(cap_x, cap_hi, **cap_kw))
43254330
# draw the medians
4331+
median_kw.setdefault('label', '_nolegend_')
43264332
medians.append(do_plot(med_x, med_y, **median_kw))
43274333
# maybe draw the means
43284334
if showmeans:
@@ -4335,6 +4341,7 @@ def do_patch(xs, ys, **kwargs):
43354341
means.append(do_plot([pos], [stats['mean']], **mean_kw))
43364342
# maybe draw the fliers
43374343
if showfliers:
4344+
flier_kw.setdefault('label', '_nolegend_')
43384345
flier_x = np.full(len(stats['fliers']), pos, dtype=np.float64)
43394346
flier_y = stats['fliers']
43404347
fliers.append(do_plot(flier_x, flier_y, **flier_kw))

lib/matplotlib/tests/test_legend.py

+30
Original file line numberDiff line numberDiff line change
@@ -1427,3 +1427,33 @@ def test_legend_text():
14271427
leg_bboxes.append(
14281428
leg.get_window_extent().transformed(ax.transAxes.inverted()))
14291429
assert_allclose(leg_bboxes[1].bounds, leg_bboxes[0].bounds)
1430+
1431+
1432+
def test_boxplot_legend():
1433+
# Test that boxplot legends handles are patches
1434+
# and labels are generated from boxplot's labels parameter.
1435+
fig, axs = plt.subplots()
1436+
A = 5*np.random.rand(100, 1)
1437+
B = 10*np.random.rand(100, 1) - 5
1438+
C = 7*np.random.rand(100, 1) - 5
1439+
labels = ['a', 'b', 'c']
1440+
1441+
bp0 = axs.boxplot(A, positions=[0], patch_artist=True, labels=labels[0])
1442+
bp1 = axs.boxplot(B, positions=[1], patch_artist=True, labels=labels[1])
1443+
bp2 = axs.boxplot(C, positions=[2], patch_artist=True, labels=labels[2])
1444+
# red, blue, green
1445+
colors = [(1.0, 0.0, 0.0, 1), (0.0, 0.0, 1.0, 1), (0.0, 0.5, 0.0, 1)]
1446+
box_list = [bp0, bp1, bp2]
1447+
# Set colors to the boxes
1448+
lbl_index = 0
1449+
for b_plot, color in zip(box_list, colors):
1450+
for patch in b_plot['boxes']:
1451+
patch.set_color(color)
1452+
lbl_index += 1
1453+
1454+
legend = axs.legend()
1455+
for index, handle in enumerate(legend.legend_handles):
1456+
assert isinstance(handle, mpl.patches.Rectangle)
1457+
assert handle.get_facecolor() == colors[index]
1458+
assert handle.get_edgecolor() == colors[index]
1459+
assert handle.get_label() == labels[index]

0 commit comments

Comments
 (0)