Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
41 changes: 41 additions & 0 deletions lib/matplotlib/tests/test_text.py
Original file line number Diff line number Diff line change
Expand Up @@ -753,6 +753,47 @@ def test_wrap_no_wrap():
assert text._get_wrapped_text() == 'non wrapped text'


@pytest.mark.parametrize(
"x, y, rotation",
[(0.0, 1.0, 0),
(1.0, 0.5, 90),
(0.5, 1.0, 180),
(0.0, 0.5, 270)])
def test_wrap_on_figure_edge(x, y, rotation):
# Regression test for #31537 - wrap collapsed to zero on figure edges.
s = 'This is a very long text that should be wrapped multiple times.'
fig = plt.figure(figsize=(6, 4))
t = fig.text(x, y, s, wrap=True, rotation=rotation)
fig.canvas.draw()

# Compare to a nudged-off-the-edge reference that should wrap the same.
nudge = 1e-4
x_ref = x - nudge if x == 1.0 else x + nudge if x == 0.0 else x
y_ref = y - nudge if y == 1.0 else y + nudge if y == 0.0 else y
fig_ref = plt.figure(figsize=(6, 4))
t_ref = fig_ref.text(x_ref, y_ref, s, wrap=True, rotation=rotation)
fig_ref.canvas.draw()

assert t._get_wrapped_text() == t_ref._get_wrapped_text()


def test_wrap_on_figure_edge_transform_rotates_text():
# With transform_rotates_text=True, get_rotation() goes through
# transform_angles() and can return near-cardinal angles with float
# noise (e.g. -90.00000000000003 for a 270 degree rotation), which
# used to skip the cardinal-angle short-circuit in _get_dist_to_box.
from matplotlib.transforms import Affine2D
fig = plt.figure(figsize=(6, 4))
s = 'This is a very long text that should be wrapped multiple times.'
# rotate_deg(90).rotate_deg(-90) is identity geometrically, but carries
# enough numerical slop to perturb transform_angles.
transform = Affine2D().rotate_deg(90).rotate_deg(-90) + fig.transFigure
t = fig.text(0.0, 0.5, s, transform=transform, wrap=True, rotation=270,
transform_rotates_text=True)
fig.canvas.draw()
assert any(' ' in line for line in t._get_wrapped_text().split('\n'))


@check_figures_equal()
def test_buffer_size(fig_test, fig_ref):
# On old versions of the Agg renderer, large non-ascii single-character
Expand Down
15 changes: 15 additions & 0 deletions lib/matplotlib/text.py
Original file line number Diff line number Diff line change
Expand Up @@ -757,6 +757,21 @@ def _get_dist_to_box(self, rotation, x0, y0, figure_box):
Return the distance from the given points to the boundaries of a
rotated box, in pixels.
"""
# Normalize rotation; transform_angles can return values outside
# [0, 360) with tiny float noise.
rotation = rotation % 360
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

AFAICS this is already done within set_rotation or get_rotation.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yep, missed that. Dropping the % 360 line.

# Short-circuit cardinal angles, otherwise cos(radians(90)) makes
# the trig formula below blow up when the text is on the edge.
tol = 1e-10
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why choose a / exactly this tolerance?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Picked it a few orders of magnitude above the float noise I saw, but with the existing % 360 in get_rotation, the tolerance isn't actually needed. Removing it.

if rotation < tol or rotation > 360 - tol:
return figure_box.x1 - x0
if abs(rotation - 90) < tol:
return figure_box.y1 - y0
if abs(rotation - 180) < tol:
return x0 - figure_box.x0
if abs(rotation - 270) < tol:
return y0 - figure_box.y0

if rotation > 270:
quad = rotation - 270
h1 = (y0 - figure_box.y0) / math.cos(math.radians(quad))
Expand Down
Loading