Skip to content

TST: Use placeholders for text in layout tests #29872

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

Merged
merged 4 commits into from
Apr 10, 2025
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions doc/devel/testing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,10 @@ the tests, they should now pass.

It is preferred that new tests use ``style='mpl20'`` as this leads to smaller
figures and reflects the newer look of default Matplotlib plots. Also, if the
texts (labels, tick labels, etc) are not really part of what is tested, use
``remove_text=True`` as this will lead to smaller figures and reduce possible
issues with font mismatch on different platforms.
texts (labels, tick labels, etc) are not really part of what is tested, use the
``remove_text=True`` argument or add the ``text_placeholders`` fixture as this
will lead to smaller figures and reduce possible issues with font mismatch on
different platforms.


Compare two methods of creating an image
Expand Down
51 changes: 51 additions & 0 deletions lib/matplotlib/testing/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,3 +125,54 @@ def test_imshow_xarray(xr):

xr = pytest.importorskip('xarray')
return xr


@pytest.fixture
def text_placeholders(monkeypatch):
"""
Replace texts with placeholder rectangles.

The rectangle size only depends on the font size and the number of characters. It is
thus insensitive to font properties and rendering details. This should be used for
tests that depend on text geometries but not the actual text rendering, e.g. layout
tests.
"""
from matplotlib.patches import Rectangle

def patched_get_text_metrics_with_cache(renderer, text, fontprop, ismath, dpi):
"""
Replace ``_get_text_metrics_with_cache`` with fixed results.

The usual ``renderer.get_text_width_height_descent`` would depend on font
metrics; instead the fixed results are based on font size and the length of the
string only.
"""
# While get_window_extent returns pixels and font size is in points, font size
# includes ascenders and descenders. Leaving out this factor and setting
# descent=0 ends up with a box that is relatively close to DejaVu Sans.
height = fontprop.get_size()
width = len(text) * height / 1.618 # Golden ratio for character size.
descent = 0
return width, height, descent

def patched_text_draw(self, renderer):
"""
Replace ``Text.draw`` with a fixed bounding box Rectangle.

The bounding box corresponds to ``Text.get_window_extent``, which ultimately
depends on the above patched ``_get_text_metrics_with_cache``.
"""
if renderer is not None:
self._renderer = renderer
if not self.get_visible():
return
if self.get_text() == '':
return
bbox = self.get_window_extent()
rect = Rectangle(bbox.p0, bbox.width, bbox.height,
facecolor=self.get_color(), edgecolor='none')
rect.draw(renderer)

monkeypatch.setattr('matplotlib.text._get_text_metrics_with_cache',
patched_get_text_metrics_with_cache)
monkeypatch.setattr('matplotlib.text.Text.draw', patched_text_draw)
2 changes: 2 additions & 0 deletions lib/matplotlib/testing/conftest.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@ def mpl_test_settings(request: pytest.FixtureRequest) -> None: ...
def pd() -> ModuleType: ...
@pytest.fixture
def xr() -> ModuleType: ...
@pytest.fixture
def text_placeholders(monkeypatch: pytest.MonkeyPatch) -> None: ...
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading