From 81a9464a934f2e623967af8f0186e52a36e08e8f Mon Sep 17 00:00:00 2001 From: Eric Firing Date: Wed, 19 May 2021 09:24:24 -1000 Subject: [PATCH 1/2] Simplify legend handler for PolyCollections. Closes #20258. Alternative to #20260. --- lib/matplotlib/legend_handler.py | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/lib/matplotlib/legend_handler.py b/lib/matplotlib/legend_handler.py index 45fb759d7b23..4f371f26d8b6 100644 --- a/lib/matplotlib/legend_handler.py +++ b/lib/matplotlib/legend_handler.py @@ -734,32 +734,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): From 155ae9f4a89993c59275291942680a1194b04894 Mon Sep 17 00:00:00 2001 From: Eric Firing Date: Wed, 19 May 2021 09:34:51 -1000 Subject: [PATCH 2/2] Add test stolen from @jklymak #20260; fix flake8 warning. --- lib/matplotlib/legend_handler.py | 1 - lib/matplotlib/tests/test_legend.py | 8 ++++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/matplotlib/legend_handler.py b/lib/matplotlib/legend_handler.py index 4f371f26d8b6..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): diff --git a/lib/matplotlib/tests/test_legend.py b/lib/matplotlib/tests/test_legend.py index b41c57469573..c7c7d2544a73 100644 --- a/lib/matplotlib/tests/test_legend.py +++ b/lib/matplotlib/tests/test_legend.py @@ -765,3 +765,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()