Skip to content
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

Fix Numpy 2.0 related test failures #27657

Merged
merged 1 commit into from
Jan 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions lib/matplotlib/pylab.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@
bytes = __import__("builtins").bytes
# We also don't want the numpy version of these functions
abs = __import__("builtins").abs
bool = __import__("builtins").bool
max = __import__("builtins").max
min = __import__("builtins").min
pow = __import__("builtins").pow
round = __import__("builtins").round
23 changes: 14 additions & 9 deletions lib/matplotlib/tests/test_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -5743,7 +5743,12 @@ def test_text_labelsize():
ax.tick_params(direction='out')


@image_comparison(['pie_default.png'])
# Note: The `pie` image tests were affected by Numpy 2.0 changing promotions
# (NEP 50). While the changes were only marginal, tolerances were introduced.
# These tolerances could likely go away when numpy 2.0 is the minimum supported
# numpy and the images are regenerated.
Comment on lines +5746 to +5749
Copy link
Member

@QuLogic QuLogic Jan 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like this is caused by:

# The use of float32 is "historical", but can't be changed without
# regenerating the test baselines.
x = np.asarray(x, np.float32)

(which ironically is to avoid changing test images), so it could be fixed by explicitly upcasting again:

diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py
index b1343b5c65..d035e9b042 100644
--- a/lib/matplotlib/axes/_axes.py
+++ b/lib/matplotlib/axes/_axes.py
@@ -3284,7 +3284,7 @@ class Axes(_AxesBase):
         slices = []
         autotexts = []

-        for frac, label, expl in zip(x, labels, explode):
+        for frac, label, expl in zip(x.astype(np.float64), labels, explode):
             x, y = center
             theta2 = (theta1 + frac) if counterclock else (theta1 - frac)
             thetam = 2 * np.pi * 0.5 * (theta1 + theta2)


@image_comparison(['pie_default.png'], tol=0.01)
def test_pie_default():
# The slices will be ordered and plotted counter-clockwise.
labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
Expand All @@ -5756,7 +5761,7 @@ def test_pie_default():


@image_comparison(['pie_linewidth_0', 'pie_linewidth_0', 'pie_linewidth_0'],
extensions=['png'], style='mpl20')
extensions=['png'], style='mpl20', tol=0.01)
def test_pie_linewidth_0():
# The slices will be ordered and plotted counter-clockwise.
labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
Expand Down Expand Up @@ -5788,7 +5793,7 @@ def test_pie_linewidth_0():
plt.axis('equal')


@image_comparison(['pie_center_radius.png'], style='mpl20')
@image_comparison(['pie_center_radius.png'], style='mpl20', tol=0.005)
def test_pie_center_radius():
# The slices will be ordered and plotted counter-clockwise.
labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
Expand All @@ -5808,7 +5813,7 @@ def test_pie_center_radius():
plt.axis('equal')


@image_comparison(['pie_linewidth_2.png'], style='mpl20')
@image_comparison(['pie_linewidth_2.png'], style='mpl20', tol=0.01)
def test_pie_linewidth_2():
# The slices will be ordered and plotted counter-clockwise.
labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
Expand All @@ -5823,7 +5828,7 @@ def test_pie_linewidth_2():
plt.axis('equal')


@image_comparison(['pie_ccw_true.png'], style='mpl20')
@image_comparison(['pie_ccw_true.png'], style='mpl20', tol=0.01)
def test_pie_ccw_true():
# The slices will be ordered and plotted counter-clockwise.
labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
Expand All @@ -5838,7 +5843,7 @@ def test_pie_ccw_true():
plt.axis('equal')


@image_comparison(['pie_frame_grid.png'], style='mpl20')
@image_comparison(['pie_frame_grid.png'], style='mpl20', tol=0.002)
def test_pie_frame_grid():
# The slices will be ordered and plotted counter-clockwise.
labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
Expand All @@ -5865,7 +5870,7 @@ def test_pie_frame_grid():
plt.axis('equal')


@image_comparison(['pie_rotatelabels_true.png'], style='mpl20')
@image_comparison(['pie_rotatelabels_true.png'], style='mpl20', tol=0.009)
def test_pie_rotatelabels_true():
# The slices will be ordered and plotted counter-clockwise.
labels = 'Hogwarts', 'Frogs', 'Dogs', 'Logs'
Expand All @@ -5880,7 +5885,7 @@ def test_pie_rotatelabels_true():
plt.axis('equal')


@image_comparison(['pie_no_label.png'])
@image_comparison(['pie_no_label.png'], tol=0.01)
def test_pie_nolabel_but_legend():
labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
sizes = [15, 30, 45, 10]
Expand All @@ -5894,7 +5899,7 @@ def test_pie_nolabel_but_legend():
plt.legend()


@image_comparison(['pie_shadow.png'], style='mpl20')
@image_comparison(['pie_shadow.png'], style='mpl20', tol=0.002)
def test_pie_shadow():
# Also acts as a test for the shade argument of Shadow
sizes = [15, 30, 45, 10]
Expand Down
16 changes: 8 additions & 8 deletions lib/matplotlib/tests/test_colors.py
Original file line number Diff line number Diff line change
Expand Up @@ -1379,38 +1379,38 @@ def test_scalarmappable_to_rgba(bytes):
# uint8 RGBA
x = np.ones((2, 3, 4), dtype=np.uint8)
expected = x.copy() if bytes else x.astype(np.float32)/255
np.testing.assert_array_equal(sm.to_rgba(x, bytes=bytes), expected)
np.testing.assert_almost_equal(sm.to_rgba(x, bytes=bytes), expected)
# uint8 RGB
expected[..., 3] = alpha_1
np.testing.assert_array_equal(sm.to_rgba(x[..., :3], bytes=bytes), expected)
np.testing.assert_almost_equal(sm.to_rgba(x[..., :3], bytes=bytes), expected)
# uint8 masked RGBA
xm = np.ma.masked_array(x, mask=np.zeros_like(x))
xm.mask[0, 0, 0] = True
expected = x.copy() if bytes else x.astype(np.float32)/255
expected[0, 0, 3] = 0
np.testing.assert_array_equal(sm.to_rgba(xm, bytes=bytes), expected)
np.testing.assert_almost_equal(sm.to_rgba(xm, bytes=bytes), expected)
# uint8 masked RGB
expected[..., 3] = alpha_1
expected[0, 0, 3] = 0
np.testing.assert_array_equal(sm.to_rgba(xm[..., :3], bytes=bytes), expected)
np.testing.assert_almost_equal(sm.to_rgba(xm[..., :3], bytes=bytes), expected)

# float RGBA
x = np.ones((2, 3, 4), dtype=float) * 0.5
expected = (x * 255).astype(np.uint8) if bytes else x.copy()
np.testing.assert_array_equal(sm.to_rgba(x, bytes=bytes), expected)
np.testing.assert_almost_equal(sm.to_rgba(x, bytes=bytes), expected)
# float RGB
expected[..., 3] = alpha_1
np.testing.assert_array_equal(sm.to_rgba(x[..., :3], bytes=bytes), expected)
np.testing.assert_almost_equal(sm.to_rgba(x[..., :3], bytes=bytes), expected)
# float masked RGBA
xm = np.ma.masked_array(x, mask=np.zeros_like(x))
xm.mask[0, 0, 0] = True
expected = (x * 255).astype(np.uint8) if bytes else x.copy()
expected[0, 0, 3] = 0
np.testing.assert_array_equal(sm.to_rgba(xm, bytes=bytes), expected)
np.testing.assert_almost_equal(sm.to_rgba(xm, bytes=bytes), expected)
# float masked RGB
expected[..., 3] = alpha_1
expected[0, 0, 3] = 0
np.testing.assert_array_equal(sm.to_rgba(xm[..., :3], bytes=bytes), expected)
np.testing.assert_almost_equal(sm.to_rgba(xm[..., :3], bytes=bytes), expected)


def test_failed_conversions():
Expand Down