From 88da530b056afffd6e2a494264f3689d48eb84e5 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Thu, 20 May 2021 00:42:17 -0400 Subject: [PATCH] Backport PR #20265: Legend edgecolor face --- lib/matplotlib/legend_handler.py | 31 +++++++++++++---------------- lib/matplotlib/tests/test_legend.py | 8 ++++++++ 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/lib/matplotlib/legend_handler.py b/lib/matplotlib/legend_handler.py index 45fb759d7b23..016bf8d3adf8 100644 --- a/lib/matplotlib/legend_handler.py +++ b/lib/matplotlib/legend_handler.py @@ -31,7 +31,6 @@ def legend_artist(self, legend, orig_handle, fontsize, handlebox) from matplotlib.lines import Line2D from matplotlib.patches import Rectangle import matplotlib.collections as mcoll -import matplotlib.colors as mcolors def update_from_first_child(tgt, src): @@ -734,32 +733,30 @@ class HandlerPolyCollection(HandlerBase): """ def _update_prop(self, legend_handle, orig_handle): def first_color(colors): - if colors is None: - return None - colors = mcolors.to_rgba_array(colors) - if len(colors): - return colors[0] - else: - return "none" + if colors.size == 0: + return (0, 0, 0, 0) + return tuple(colors[0]) def get_first(prop_array): if len(prop_array): return prop_array[0] else: return None - edgecolor = getattr(orig_handle, '_original_edgecolor', - orig_handle.get_edgecolor()) - legend_handle.set_edgecolor(first_color(edgecolor)) - facecolor = getattr(orig_handle, '_original_facecolor', - orig_handle.get_facecolor()) - legend_handle.set_facecolor(first_color(facecolor)) - legend_handle.set_fill(orig_handle.get_fill()) - legend_handle.set_hatch(orig_handle.get_hatch()) + + # orig_handle is a PolyCollection and legend_handle is a Patch. + # Directly set Patch color attributes (must be RGBA tuples). + legend_handle._facecolor = first_color(orig_handle.get_facecolor()) + legend_handle._edgecolor = first_color(orig_handle.get_edgecolor()) + legend_handle._fill = orig_handle.get_fill() + legend_handle._hatch = orig_handle.get_hatch() + # Hatch color is anomalous in having no getters and setters. + legend_handle._hatch_color = orig_handle._hatch_color + # Setters are fine for the remaining attributes. legend_handle.set_linewidth(get_first(orig_handle.get_linewidths())) legend_handle.set_linestyle(get_first(orig_handle.get_linestyles())) legend_handle.set_transform(get_first(orig_handle.get_transforms())) legend_handle.set_figure(orig_handle.get_figure()) - legend_handle.set_alpha(orig_handle.get_alpha()) + # Alpha is already taken into account by the color attributes. def create_artists(self, legend, orig_handle, xdescent, ydescent, width, height, fontsize, trans): diff --git a/lib/matplotlib/tests/test_legend.py b/lib/matplotlib/tests/test_legend.py index 12356ae15667..782ef87853fe 100644 --- a/lib/matplotlib/tests/test_legend.py +++ b/lib/matplotlib/tests/test_legend.py @@ -734,3 +734,11 @@ def test_plot_multiple_label_incorrect_length_exception(): label = ['high', 'low', 'medium'] fig, ax = plt.subplots() ax.plot(x, y, label=label) + + +def test_legend_face_edgecolor(): + # Smoke test for PolyCollection legend handler with 'face' edgecolor. + fig, ax = plt.subplots() + ax.fill_between([0, 1, 2], [1, 2, 3], [2, 3, 4], + facecolor='r', edgecolor='face', label='Fill') + ax.legend()