Skip to content

ENH: Add option to relpace text with boxes in image_comparision test #29871

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

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions lib/matplotlib/testing/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import matplotlib.units
import matplotlib.testing
from matplotlib import _pylab_helpers, cbook, ft2font, pyplot as plt, ticker
import matplotlib.text as mtext
from .compare import comparable_formats, compare_images, make_test_filename
from .exceptions import ImageComparisonFailure

Expand Down Expand Up @@ -117,11 +118,12 @@ class _ImageComparisonBase:
any code that would be specific to any testing framework.
"""

def __init__(self, func, tol, remove_text, savefig_kwargs):
def __init__(self, func, tol, remove_text, replace_text, savefig_kwargs):
self.func = func
self.baseline_dir, self.result_dir = _image_directories(func)
self.tol = tol
self.remove_text = remove_text
self.replace_text = replace_text
self.savefig_kwargs = savefig_kwargs

def copy_baseline(self, baseline, extension):
Expand Down Expand Up @@ -164,19 +166,23 @@ def compare(self, fig, baseline, extension, *, _lock=False):
lock = (cbook._lock_path(actual_path)
if _lock else contextlib.nullcontext())
with lock:
if self.replace_text:
mtext.Text._draw_bbox_only = True
try:
fig.savefig(actual_path, **kwargs)
finally:
# Matplotlib has an autouse fixture to close figures, but this
# makes things more convenient for third-party users.
plt.close(fig)
if self.replace_text:
mtext.Text._draw_bbox_only = False
expected_path = self.copy_baseline(baseline, extension)
_raise_on_image_difference(expected_path, actual_path, self.tol)


def _pytest_image_comparison(baseline_images, extensions, tol,
freetype_version, remove_text, savefig_kwargs,
style):
freetype_version, remove_text, replace_text,
savefig_kwargs, style):
"""
Decorate function with image comparison for pytest.

Expand Down Expand Up @@ -212,6 +218,7 @@ def wrapper(*args, extension, request, **kwargs):
pytest.skip(f"Cannot compare {extension} files {reason}")

img = _ImageComparisonBase(func, tol=tol, remove_text=remove_text,
replace_text=replace_text,
savefig_kwargs=savefig_kwargs)
matplotlib.testing.set_font_settings_for_testing()

Expand Down Expand Up @@ -259,6 +266,7 @@ def wrapper(*args, extension, request, **kwargs):

def image_comparison(baseline_images, extensions=None, tol=0,
freetype_version=None, remove_text=False,
replace_text=False,
savefig_kwarg=None,
# Default of mpl_test_settings fixture and cleanup too.
style=("classic", "_classic_test_patch")):
Expand Down Expand Up @@ -344,6 +352,7 @@ def image_comparison(baseline_images, extensions=None, tol=0,
return _pytest_image_comparison(
baseline_images=baseline_images, extensions=extensions, tol=tol,
freetype_version=freetype_version, remove_text=remove_text,
replace_text=replace_text,
savefig_kwargs=savefig_kwarg, style=style)


Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions lib/matplotlib/tests/test_text.py
Original file line number Diff line number Diff line change
Expand Up @@ -1190,3 +1190,15 @@ def test_ytick_rotation_mode():
tick.set_rotation(angle)

plt.subplots_adjust(left=0.4, right=0.6, top=.99, bottom=.01)


@image_comparison(baseline_images=['replace_text'],
replace_text=True, extensions=['png'], style='mpl20')
def test_replace_text():
fig, ax = plt.subplots()
ax.plot([2, 1], label='line 1')
ax.plot([3, 2], label='line 2')
ax.legend(title='mylegend')
ax.set_title('testing text replacement')
ax.set_xlabel('xlabel')
ax.set_ylabel('ylabel')
13 changes: 13 additions & 0 deletions lib/matplotlib/text.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,13 @@ class Text(Artist):

zorder = 3
_charsize_cache = dict()
_draw_bbox_only = False
"""
A helper flag to replace texts by a bounding box. This is primarily
intended for use in figure comparison tests.
For sipmlicity, the flag is evaluated at draw time and thus applies
Copy link
Preview

Copilot AI Apr 5, 2025

Choose a reason for hiding this comment

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

There is a spelling error in the word 'sipmlicity'; consider correcting it to 'simplicity'.

Suggested change
For sipmlicity, the flag is evaluated at draw time and thus applies
For simplicity, the flag is evaluated at draw time and thus applies

Copilot uses AI. Check for mistakes.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ok, just wanted to try what copilot review suggested.

Copy link
Member

Choose a reason for hiding this comment

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

It didn't even manage to catch the typos in the PR title...

to all drawn text.
"""

def __repr__(self):
return f"Text({self._x}, {self._y}, {self._text!r})"
Expand Down Expand Up @@ -778,6 +785,9 @@ def draw(self, renderer):

# Update the location and size of the bbox
# (`.patches.FancyBboxPatch`), and draw it.
if self._draw_bbox_only:
self.set_bbox(dict(facecolor='none', edgecolor='red', pad=0))

if self._bbox_patch:
self.update_bbox_position_size(renderer)
self._bbox_patch.draw(renderer)
Expand All @@ -793,6 +803,9 @@ def draw(self, renderer):

for line, wh, x, y in info:

if self._draw_bbox_only:
break

mtext = self if len(info) == 1 else None
x = x + posx
y = y + posy
Expand Down
Loading