diff --git a/lib/matplotlib/markers.py b/lib/matplotlib/markers.py index fa5e66e73ade..da6d1ba8c8e2 100644 --- a/lib/matplotlib/markers.py +++ b/lib/matplotlib/markers.py @@ -261,7 +261,8 @@ def _recache(self): # set to 'none'. The marker function will override this for unfilled # markers. self._filled = self._fillstyle != 'none' - self._marker_function() + func = getattr(self, self._marker_function) + func() def __bool__(self): return bool(len(self._path.vertices)) @@ -308,23 +309,23 @@ def _set_marker(self, marker): `matplotlib.markers`. """ if isinstance(marker, str) and cbook.is_math_text(marker): - self._marker_function = self._set_mathtext_path + self._marker_function = '_set_mathtext_path' elif isinstance(marker, (int, str)) and marker in self.markers: - self._marker_function = getattr(self, '_set_' + self.markers[marker]) + self._marker_function = f'_set_{self.markers[marker]}' elif (isinstance(marker, np.ndarray) and marker.ndim == 2 and marker.shape[1] == 2): - self._marker_function = self._set_vertices + self._marker_function = '_set_vertices' elif isinstance(marker, Path): - self._marker_function = self._set_path_marker + self._marker_function = '_set_path_marker' elif (isinstance(marker, Sized) and len(marker) in (2, 3) and marker[1] in (0, 1, 2)): - self._marker_function = self._set_tuple_marker + self._marker_function = '_set_tuple_marker' elif isinstance(marker, MarkerStyle): - self.__dict__ = copy.deepcopy(marker.__dict__) + self.__dict__.update(copy.deepcopy(marker.__dict__)) else: try: Path(marker) - self._marker_function = self._set_vertices + self._marker_function = '_set_vertices' except ValueError as err: raise ValueError( f'Unrecognized marker style {marker!r}') from err diff --git a/lib/matplotlib/testing/compare.py b/lib/matplotlib/testing/compare.py index 87b3958a6e17..c6c29ab3306a 100644 --- a/lib/matplotlib/testing/compare.py +++ b/lib/matplotlib/testing/compare.py @@ -392,7 +392,7 @@ def _load_image(path): return np.asarray(img) -def compare_images(expected, actual, tol, in_decorator=False): +def compare_images(expected, actual, tol, in_decorator=False, *, deadband=0): """ Compare two "image" files checking differences within a tolerance. @@ -469,11 +469,16 @@ def compare_images(expected, actual, tol, in_decorator=False): if np.array_equal(expected_image, actual_image): return None - rms, abs_diff = _image.calculate_rms_and_diff(expected_image, actual_image) + rms, abs_diff, max_difference = _image.calculate_rms_and_diff( + expected_image, actual_image + ) if rms <= tol: return None + if max_difference <= deadband: + return None + Image.fromarray(abs_diff).save(diff_image, format="png") results = dict(rms=rms, expected=str(expected), diff --git a/pyproject.toml b/pyproject.toml index 48a174731440..5d2221326f20 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -234,7 +234,8 @@ exclude = [ "lib/matplotlib/tests/", # tinypages is used for testing the sphinx ext, # stubtest will import and run, opening a figure if not excluded - ".*/tinypages" + ".*/tinypages", + "lib/matplotlib/pylab.py" ] files = [ "lib/matplotlib", diff --git a/src/_image_wrapper.cpp b/src/_image_wrapper.cpp index e1cd5b628084..36745a3fff19 100644 --- a/src/_image_wrapper.cpp +++ b/src/_image_wrapper.cpp @@ -249,6 +249,7 @@ calculate_rms_and_diff(py::array_t expected_image, py::array_t diff_image(diff_dims); auto diff = diff_image.mutable_unchecked<3>(); + auto max_difference = 0; double total = 0.0; for (auto i = 0; i < height; i++) { for (auto j = 0; j < width; j++) { @@ -257,7 +258,7 @@ calculate_rms_and_diff(py::array_t expected_image, static_cast(actual(i, j, k)); total += pixel_diff*pixel_diff; - + max_difference = max_difference < abs(pixel_diff) ? abs(pixel_diff) : max_difference; if (k != 3) { // Hard-code a fully solid alpha channel by omitting it. diff(i, j, k) = static_cast(std::clamp( abs(pixel_diff) * 10, // Expand differences in luminance domain. @@ -268,7 +269,7 @@ calculate_rms_and_diff(py::array_t expected_image, } total = total / (width * height * depth); - return py::make_tuple(sqrt(total), diff_image); + return py::make_tuple(sqrt(total), diff_image, max_difference); }