-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
matplotlib 3.5.0b1 breaks test suite #2663
Comments
Does something like this work? diff --git a/seaborn/tests/test_categorical.py b/seaborn/tests/test_categorical.py
index d4e09b7..bb5bc51 100644
--- a/seaborn/tests/test_categorical.py
+++ b/seaborn/tests/test_categorical.py
@@ -1,5 +1,6 @@
import itertools
from functools import partial
+from unittest.mock import patch
import numpy as np
import pandas as pd
@@ -852,15 +853,17 @@ class TestBoxPlotter(CategoricalFixture):
p.establish_variables("h", "y", "g", data=self.df)
npt.assert_array_almost_equal(p.hue_offsets, [-.2, 0, .2])
- def test_axes_data(self):
+ @patch('matplotlib.axes.Axes.boxplot')
+ def test_axes_data(self, boxplot):
- ax = cat.boxplot(x="g", y="y", data=self.df)
- assert len(ax.artists) == 3
+ cat.boxplot(x="g", y="y", data=self.df)
+ assert boxplot.call_count == 3
plt.close("all")
+ boxplot.reset_mock()
- ax = cat.boxplot(x="g", y="y", hue="h", data=self.df)
- assert len(ax.artists) == 6
+ cat.boxplot(x="g", y="y", hue="h", data=self.df)
+ assert boxplot.call_count == 6
plt.close("all")
I think this preserves the intent of this test, but I have not looked at all of them, and it may not work for all. |
Hm I've never really thought about patching matplotlib functions and checking the call count. I actually think this would fail here because in the first case I think the way forward here is to have a |
No, it does passes. The seaborn |
Ah, I just realized that some tests that |
Ah, seems you're right. Those functions aren't so consistent ... That zip issue is a recurring frustration! |
So the problem with switching to I experimented a bit with catching the results with a mock patch, but it looks like you have to do a few steps to capture return values. I pulled that together into a context manager, which looks like the following: diff --git a/seaborn/tests/test_categorical.py b/seaborn/tests/test_categorical.py
index d4e09b7..fcea099 100644
--- a/seaborn/tests/test_categorical.py
+++ b/seaborn/tests/test_categorical.py
@@ -1,5 +1,8 @@
+from contextlib import contextmanager
import itertools
+import functools
from functools import partial
+from unittest import mock
import numpy as np
import pandas as pd
@@ -503,6 +506,21 @@ class TestCategoricalPlotter(CategoricalFixture):
assert p.colors == [(.25, .25, .75), (.75, .25, .25), (1, 1, 1)]
+@contextmanager
+def return_value_collector(obj, method_name):
+ func = getattr(obj, method_name)
+ collection = []
+
+ @functools.wraps(func)
+ def wrapper(*args, **kwargs):
+ result = func(*args, **kwargs)
+ collection.append(result)
+ return result
+
+ with mock.patch.object(obj, method_name, side_effect=wrapper):
+ yield collection
+
+
class TestCategoricalStatPlotter(CategoricalFixture):
def test_no_bootstrappig(self):
@@ -854,53 +872,67 @@ class TestBoxPlotter(CategoricalFixture):
def test_axes_data(self):
- ax = cat.boxplot(x="g", y="y", data=self.df)
- assert len(ax.artists) == 3
+ fig, ax = plt.subplots()
+ with return_value_collector(ax, 'boxplot') as bxp_artists:
+ cat.boxplot(x="g", y="y", data=self.df, ax=ax)
+ assert len(bxp_artists) == 3
plt.close("all")
- ax = cat.boxplot(x="g", y="y", hue="h", data=self.df)
- assert len(ax.artists) == 6
+ fig, ax = plt.subplots()
+ with return_value_collector(ax, 'boxplot') as bxp_artists:
+ cat.boxplot(x="g", y="y", hue="h", data=self.df, ax=ax)
+ assert len(bxp_artists) == 6
plt.close("all")
def test_box_colors(self):
- 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):
- assert patch.get_facecolor()[:3] == color
+ fig, ax = plt.subplots()
+ with return_value_collector(ax, 'boxplot') as bxp_artists:
+ cat.boxplot(x="g", y="y", data=self.df, saturation=1, ax=ax)
+
+ pal = palettes.color_palette(n_colors=3)
+ for bxp, color in itertools.zip_longest(bxp_artists, pal):
+ patch, = bxp['boxes'] # There must be 1 only.
+ 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):
- assert patch.get_facecolor()[:3] == color
+ fig, ax = plt.subplots()
+ with return_value_collector(ax, 'boxplot') as bxp_artists:
+ cat.boxplot(x="g", y="y", hue="h", data=self.df, saturation=1, ax=ax)
+
+ pal = palettes.color_palette(n_colors=2)
+ for bxp, color in itertools.zip_longest(bxp_artists, pal * 2):
+ patch, = bxp['boxes'] # There must be 1 only.
+ assert patch.get_facecolor()[:3] == color
plt.close("all")
Note, this does require knowing that Matplotlb's |
Alternately, could just change the tests to look for Or we could exclude the patches that get added for the legend by counting patches that don't have a label. |
As was noted in mwaskom#2663 (comment), the `test_box_colors` tests are broken because `zip` only iterates to the shortest input. For boxplot, there are in fact 3 copies of the palette not 2. For boxenplot, it doesn't add `Patch` at all but `PatchCollection`, as can be seen in the related tests.
As was noted in #2663 (comment), the `test_box_colors` tests are broken because `zip` only iterates to the shortest input. For boxplot, there are in fact 3 copies of the palette not 2. For boxenplot, it doesn't add `Patch` at all but `PatchCollection`, as can be seen in the related tests.
I'm pretty sure these failures are all related to things that happen as part of tests but not normal operations and so this isn't an urgent problem, but they should get addressed before the final release drops and breaks CI.
The text was updated successfully, but these errors were encountered: