From ee8dc54f758359bc1ca6ce1e0422103af629783b Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Tue, 30 Mar 2021 17:27:50 -0400 Subject: [PATCH] Copy new attributes in Collection.update_from. These were added in #18480, and not copying them can mean that an artist that used `update_from` could get in an inconsistent state. For example, this will fix legends of colour-mapped scatter plots, where a copy of the scatter Collection is made to go in the legend. Fixes #19779. --- lib/matplotlib/collections.py | 5 ++++- lib/matplotlib/tests/test_axes.py | 18 ++++++++++++------ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/lib/matplotlib/collections.py b/lib/matplotlib/collections.py index bb270b218e22..0e1d225c5209 100644 --- a/lib/matplotlib/collections.py +++ b/lib/matplotlib/collections.py @@ -944,8 +944,11 @@ def update_from(self, other): artist.Artist.update_from(self, other) self._antialiaseds = other._antialiaseds + self._mapped_colors = other._mapped_colors + self._edge_is_mapped = other._edge_is_mapped self._original_edgecolor = other._original_edgecolor self._edgecolors = other._edgecolors + self._face_is_mapped = other._face_is_mapped self._original_facecolor = other._original_facecolor self._facecolors = other._facecolors self._linewidths = other._linewidths @@ -958,7 +961,7 @@ def update_from(self, other): self._A = other._A self.norm = other.norm self.cmap = other.cmap - # do we need to copy self._update_dict? -JJL + self._update_dict = other._update_dict.copy() self.stale = True diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index aba1df408be3..93ec68285742 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -52,14 +52,16 @@ def test_get_labels(): @check_figures_equal() def test_label_loc_vertical(fig_test, fig_ref): ax = fig_test.subplots() - sc = ax.scatter([1, 2], [1, 2], c=[1, 2]) + sc = ax.scatter([1, 2], [1, 2], c=[1, 2], label='scatter') + ax.legend() ax.set_ylabel('Y Label', loc='top') ax.set_xlabel('X Label', loc='right') cbar = fig_test.colorbar(sc) cbar.set_label("Z Label", loc='top') ax = fig_ref.subplots() - sc = ax.scatter([1, 2], [1, 2], c=[1, 2]) + sc = ax.scatter([1, 2], [1, 2], c=[1, 2], label='scatter') + ax.legend() ax.set_ylabel('Y Label', y=1, ha='right') ax.set_xlabel('X Label', x=1, ha='right') cbar = fig_ref.colorbar(sc) @@ -69,14 +71,16 @@ def test_label_loc_vertical(fig_test, fig_ref): @check_figures_equal() def test_label_loc_horizontal(fig_test, fig_ref): ax = fig_test.subplots() - sc = ax.scatter([1, 2], [1, 2], c=[1, 2]) + sc = ax.scatter([1, 2], [1, 2], c=[1, 2], label='scatter') + ax.legend() ax.set_ylabel('Y Label', loc='bottom') ax.set_xlabel('X Label', loc='left') cbar = fig_test.colorbar(sc, orientation='horizontal') cbar.set_label("Z Label", loc='left') ax = fig_ref.subplots() - sc = ax.scatter([1, 2], [1, 2], c=[1, 2]) + sc = ax.scatter([1, 2], [1, 2], c=[1, 2], label='scatter') + ax.legend() ax.set_ylabel('Y Label', y=0, ha='left') ax.set_xlabel('X Label', x=0, ha='left') cbar = fig_ref.colorbar(sc, orientation='horizontal') @@ -88,14 +92,16 @@ def test_label_loc_rc(fig_test, fig_ref): with matplotlib.rc_context({"xaxis.labellocation": "right", "yaxis.labellocation": "top"}): ax = fig_test.subplots() - sc = ax.scatter([1, 2], [1, 2], c=[1, 2]) + sc = ax.scatter([1, 2], [1, 2], c=[1, 2], label='scatter') + ax.legend() ax.set_ylabel('Y Label') ax.set_xlabel('X Label') cbar = fig_test.colorbar(sc, orientation='horizontal') cbar.set_label("Z Label") ax = fig_ref.subplots() - sc = ax.scatter([1, 2], [1, 2], c=[1, 2]) + sc = ax.scatter([1, 2], [1, 2], c=[1, 2], label='scatter') + ax.legend() ax.set_ylabel('Y Label', y=1, ha='right') ax.set_xlabel('X Label', x=1, ha='right') cbar = fig_ref.colorbar(sc, orientation='horizontal')