From 262bb95402e405489f6d58bb96dcb06fcd24f0ba Mon Sep 17 00:00:00 2001 From: Michael Waskom Date: Sun, 31 Oct 2021 16:52:06 -0400 Subject: [PATCH] Update tests for compatability with matplotlib 3.5.0 (#2690) * Update boxplot tests for mpl3.5 compatability * Update kdeplot tests for mpl3.5 compatability * Update legend tests for mpl3.5 compatability * Pin docutils to avoid buggy interaction with sphinx [ flow: modified to apply on top of 0.11.2 ] Modified-by: Florian Schmaus --- seaborn/tests/test_categorical.py | 30 +++++++++------ seaborn/tests/test_distributions.py | 58 ++++++++++++++++++++--------- 3 files changed, 61 insertions(+), 28 deletions(-) diff --git a/seaborn/tests/test_categorical.py b/seaborn/tests/test_categorical.py index a0b0393c330c..ac41a8885773 100644 --- a/seaborn/tests/test_categorical.py +++ b/seaborn/tests/test_categorical.py @@ -28,6 +28,14 @@ class CategoricalFixture: df = pd.DataFrame(dict(y=y, g=g, h=h, u=u)) x_df["W"] = g + def get_box_artists(self, ax): + + if Version(mpl.__version__) < Version("3.5.0b0"): + return ax.artists + else: + # Exclude labeled patches, which are for the legend + return [p for p in ax.patches if not p.get_label()] + class TestCategoricalPlotter(CategoricalFixture): @@ -772,12 +780,12 @@ class TestBoxPlotter(CategoricalFixture): def test_axes_data(self): ax = cat.boxplot(x="g", y="y", data=self.df) - assert len(ax.artists) == 3 + assert len(self.get_box_artists(ax)) == 3 plt.close("all") ax = cat.boxplot(x="g", y="y", hue="h", data=self.df) - assert len(ax.artists) == 6 + assert len(self.get_box_artists(ax)) == 6 plt.close("all") @@ -785,14 +793,14 @@ class TestBoxPlotter(CategoricalFixture): ax = cat.boxplot(x="g", y="y", data=self.df, saturation=1) pal = palettes.color_palette(n_colors=3) - for patch, color in zip(ax.artists, pal): + for patch, color in zip(self.get_box_artists(ax), pal): assert patch.get_facecolor()[:3] == color plt.close("all") ax = cat.boxplot(x="g", y="y", hue="h", data=self.df, saturation=1) pal = palettes.color_palette(n_colors=2) - for patch, color in zip(ax.artists, pal * 2): + for patch, color in zip(self.get_box_artists(ax), pal * 2): assert patch.get_facecolor()[:3] == color plt.close("all") @@ -801,7 +809,7 @@ class TestBoxPlotter(CategoricalFixture): ax = cat.boxplot(x="g", y="y", data=self.df, order=["a", "b", "c", "d"]) - assert len(ax.artists) == 3 + assert len(self.get_box_artists(ax)) == 3 def test_missing_data(self): @@ -811,13 +819,13 @@ class TestBoxPlotter(CategoricalFixture): y[-2:] = np.nan ax = cat.boxplot(x=x, y=y) - assert len(ax.artists) == 3 + assert len(self.get_box_artists(ax)) == 3 plt.close("all") y[-1] = 0 ax = cat.boxplot(x=x, y=y, hue=h) - assert len(ax.artists) == 7 + assert len(self.get_box_artists(ax)) == 7 plt.close("all") @@ -2504,11 +2512,11 @@ class TestCatPlot(CategoricalFixture): g = cat.catplot(x="g", y="y", data=self.df, kind="box") want_artists = self.g.unique().size - assert len(g.ax.artists) == want_artists + assert len(self.get_box_artists(g.ax)) == want_artists g = cat.catplot(x="g", y="y", hue="h", data=self.df, kind="box") want_artists = self.g.unique().size * self.h.unique().size - assert len(g.ax.artists) == want_artists + assert len(self.get_box_artists(g.ax)) == want_artists g = cat.catplot(x="g", y="y", data=self.df, kind="violin", inner=None) @@ -2858,14 +2866,14 @@ class TestBoxenPlotter(CategoricalFixture): ax = cat.boxenplot(x="g", y="y", data=self.df, saturation=1) pal = palettes.color_palette(n_colors=3) - for patch, color in zip(ax.artists, pal): + for patch, color in zip(self.get_box_artists(ax), pal): assert patch.get_facecolor()[:3] == color plt.close("all") ax = cat.boxenplot(x="g", y="y", hue="h", data=self.df, saturation=1) pal = palettes.color_palette(n_colors=2) - for patch, color in zip(ax.artists, pal * 2): + for patch, color in zip(self.get_box_artists(ax), pal * 2): assert patch.get_facecolor()[:3] == color plt.close("all") diff --git a/seaborn/tests/test_distributions.py b/seaborn/tests/test_distributions.py index 737d6ccdaddc..57b380c32ca1 100644 --- a/seaborn/tests/test_distributions.py +++ b/seaborn/tests/test_distributions.py @@ -39,6 +39,27 @@ from .._testing import ( ) +def get_contour_coords(c): + """Provide compatability for change in contour artist type in mpl3.5.""" + # See https://github.com/matplotlib/matplotlib/issues/20906 + if isinstance(c, mpl.collections.LineCollection): + return c.get_segments() + elif isinstance(c, mpl.collections.PathCollection): + return [p.vertices[:np.argmax(p.codes) + 1] for p in c.get_paths()] + + +def get_contour_color(c): + """Provide compatability for change in contour artist type in mpl3.5.""" + # See https://github.com/matplotlib/matplotlib/issues/20906 + if isinstance(c, mpl.collections.LineCollection): + return c.get_color() + elif isinstance(c, mpl.collections.PathCollection): + if c.get_facecolor().size: + return c.get_facecolor() + else: + return c.get_edgecolor() + + class TestDistPlot(object): rs = np.random.RandomState(0) @@ -803,7 +824,10 @@ class TestKDEPlotUnivariate: for label, level in zip(legend_labels, order): assert label.get_text() == level - legend_artists = ax.legend_.findobj(mpl.lines.Line2D)[::2] + legend_artists = ax.legend_.findobj(mpl.lines.Line2D) + if Version(mpl.__version__) < Version("3.5.0b0"): + # https://github.com/matplotlib/matplotlib/pull/20699 + legend_artists = legend_artists[::2] palette = color_palette() for artist, color in zip(legend_artists, palette): assert to_rgb(artist.get_color()) == to_rgb(color) @@ -854,7 +878,7 @@ class TestKDEPlotBivariate: f, ax = plt.subplots() kdeplot(data=long_df, x="x", y="y", hue="c", fill=fill) for c in ax.collections: - if fill: + if fill or Version(mpl.__version__) >= Version("3.5.0b0"): assert isinstance(c, mpl.collections.PathCollection) else: assert isinstance(c, mpl.collections.LineCollection) @@ -870,8 +894,8 @@ class TestKDEPlotBivariate: kdeplot(x=x, y=y, hue=hue, common_norm=True, ax=ax1) kdeplot(x=x, y=y, hue=hue, common_norm=False, ax=ax2) - n_seg_1 = sum([len(c.get_segments()) > 0 for c in ax1.collections]) - n_seg_2 = sum([len(c.get_segments()) > 0 for c in ax2.collections]) + n_seg_1 = sum([len(get_contour_coords(c)) > 0 for c in ax1.collections]) + n_seg_2 = sum([len(get_contour_coords(c)) > 0 for c in ax2.collections]) assert n_seg_2 > n_seg_1 def test_log_scale(self, rng): @@ -898,7 +922,7 @@ class TestKDEPlotBivariate: ax2.contour(10 ** xx, yy, density, levels=levels) for c1, c2 in zip(ax1.collections, ax2.collections): - assert_array_equal(c1.get_segments(), c2.get_segments()) + assert_array_equal(get_contour_coords(c1), get_contour_coords(c2)) def test_bandwidth(self, rng): @@ -911,7 +935,7 @@ class TestKDEPlotBivariate: kdeplot(x=x, y=y, bw_adjust=2, ax=ax2) for c1, c2 in zip(ax1.collections, ax2.collections): - seg1, seg2 = c1.get_segments(), c2.get_segments() + seg1, seg2 = get_contour_coords(c1), get_contour_coords(c2) if seg1 + seg2: x1 = seg1[0][:, 0] x2 = seg2[0][:, 0] @@ -936,9 +960,9 @@ class TestKDEPlotBivariate: kdeplot(x=x, y=y, hue=hue, weights=weights, ax=ax2) for c1, c2 in zip(ax1.collections, ax2.collections): - if c1.get_segments() and c2.get_segments(): - seg1 = np.concatenate(c1.get_segments(), axis=0) - seg2 = np.concatenate(c2.get_segments(), axis=0) + if get_contour_coords(c1) and get_contour_coords(c2): + seg1 = np.concatenate(get_contour_coords(c1), axis=0) + seg2 = np.concatenate(get_contour_coords(c2), axis=0) assert not np.array_equal(seg1, seg2) def test_hue_ignores_cmap(self, long_df): @@ -946,7 +970,7 @@ class TestKDEPlotBivariate: with pytest.warns(UserWarning, match="cmap parameter ignored"): ax = kdeplot(data=long_df, x="x", y="y", hue="c", cmap="viridis") - color = tuple(ax.collections[0].get_color().squeeze()) + color = tuple(get_contour_color(ax.collections[0]).squeeze()) assert color == mpl.colors.colorConverter.to_rgba("C0") def test_contour_line_colors(self, long_df): @@ -955,7 +979,7 @@ class TestKDEPlotBivariate: ax = kdeplot(data=long_df, x="x", y="y", color=color) for c in ax.collections: - assert tuple(c.get_color().squeeze()) == color + assert tuple(get_contour_color(c).squeeze()) == color def test_contour_fill_colors(self, long_df): @@ -987,7 +1011,7 @@ class TestKDEPlotBivariate: kdeplot(**plot_kws, levels=np.linspace(thresh, 1, n), ax=ax2) for c1, c2 in zip(ax1.collections, ax2.collections): - assert_array_equal(c1.get_segments(), c2.get_segments()) + assert_array_equal(get_contour_coords(c1), get_contour_coords(c2)) with pytest.raises(ValueError): kdeplot(**plot_kws, levels=[0, 1, 2]) @@ -999,7 +1023,7 @@ class TestKDEPlotBivariate: kdeplot(**plot_kws, levels=n, thresh=0, ax=ax2) for c1, c2 in zip(ax1.collections, ax2.collections): - assert_array_equal(c1.get_segments(), c2.get_segments()) + assert_array_equal(get_contour_coords(c1), get_contour_coords(c2)) for c1, c2 in zip(ax1.collections, ax2.collections): assert_array_equal(c1.get_facecolors(), c2.get_facecolors()) @@ -2246,13 +2270,13 @@ class TestDisPlot: z = [0] * 80 + [1] * 20 g = displot(x=x, y=y, col=z, kind="kde", levels=10) - l1 = sum(bool(c.get_segments()) for c in g.axes.flat[0].collections) - l2 = sum(bool(c.get_segments()) for c in g.axes.flat[1].collections) + l1 = sum(bool(get_contour_coords(c)) for c in g.axes.flat[0].collections) + l2 = sum(bool(get_contour_coords(c)) for c in g.axes.flat[1].collections) assert l1 > l2 g = displot(x=x, y=y, col=z, kind="kde", levels=10, common_norm=False) - l1 = sum(bool(c.get_segments()) for c in g.axes.flat[0].collections) - l2 = sum(bool(c.get_segments()) for c in g.axes.flat[1].collections) + l1 = sum(bool(get_contour_coords(c)) for c in g.axes.flat[0].collections) + l2 = sum(bool(get_contour_coords(c)) for c in g.axes.flat[1].collections) assert l1 == l2 def test_bivariate_hist_norm(self, rng): -- 2.35.1