Skip to content

Resolve 'text ignores rotational part of transformation' (#698) #15532

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
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
:orphan:

Transform can rotate text direction
-----------------------------------
The new `.Text` parameter ``transform_rotates_text`` now sets whether
rotations of the transform affect the text direction.

Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
to something on the plot. In this case, the correct angle won't be
the angle of that object in the plot coordinate system, but the angle
that that object APPEARS in the screen coordinate system. This angle
is found by transforming the angle from the plot to the screen
coordinate system, as shown in the example below.
can be determined automatically by setting the parameter
*transform_rotates_text*, as shown in the example below.
"""

import matplotlib.pyplot as plt
Expand All @@ -31,12 +31,12 @@

# Rotate angle
angle = 45
trans_angle = ax.transData.transform_angles([45], l2.reshape((1, 2)))[0]

# Plot text
th1 = ax.text(*l1, 'text not rotated correctly', fontsize=16,
rotation=angle, rotation_mode='anchor')
th2 = ax.text(*l2, 'text rotated correctly', fontsize=16,
rotation=trans_angle, rotation_mode='anchor')
rotation=angle, rotation_mode='anchor',
transform_rotates_text=True)

plt.show()
10 changes: 10 additions & 0 deletions lib/matplotlib/tests/test_text.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from matplotlib.backend_bases import MouseEvent
import matplotlib.patches as mpatches
import matplotlib.pyplot as plt
import matplotlib.transforms as mtransforms
from matplotlib.testing.decorators import check_figures_equal, image_comparison


Expand Down Expand Up @@ -689,3 +690,12 @@ def test_fontproperties_kwarg_precedence():
text2 = plt.ylabel("counts", size=40.0, fontproperties='Times New Roman')
assert text1.get_size() == 40.0
assert text2.get_size() == 40.0


def test_transform_rotates_text():
ax = plt.gca()
transform = mtransforms.Affine2D().rotate_deg(30)
text = ax.text(0, 0, 'test', transform=transform,
transform_rotates_text=True)
result = text.get_rotation()
assert_almost_equal(result, 30)
30 changes: 29 additions & 1 deletion lib/matplotlib/text.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ def __init__(self,
rotation_mode=None,
usetex=None, # defaults to rcParams['text.usetex']
wrap=False,
transform_rotates_text=False,
**kwargs
):
"""
Expand All @@ -157,6 +158,7 @@ def __init__(self,
self.set_horizontalalignment(horizontalalignment)
self._multialignment = multialignment
self._rotation = rotation
self._transform_rotates_text = transform_rotates_text
self._bbox_patch = None # a FancyBboxPatch instance
self._renderer = None
if linespacing is None:
Expand Down Expand Up @@ -228,7 +230,20 @@ def _get_multialignment(self):

def get_rotation(self):
"""Return the text angle in degrees between 0 and 360."""
return get_rotation(self._rotation) # string_or_number -> number
if self.get_transform_rotates_text():
angle = get_rotation(self._rotation)
x, y = self.get_unitless_position()
angles = [angle, ]
pts = [[x, y]]
return self.get_transform().transform_angles(angles, pts).item(0)
else:
return get_rotation(self._rotation) # string_or_number -> number

def get_transform_rotates_text(self):
"""
Return whether rotations of the transform affect the text direction.
"""
return self._transform_rotates_text

def set_rotation_mode(self, m):
"""
Expand Down Expand Up @@ -259,6 +274,7 @@ def update_from(self, other):
self._fontproperties = other._fontproperties.copy()
self._usetex = other._usetex
self._rotation = other._rotation
self._transform_rotates_text = other._transform_rotates_text
self._picker = other._picker
self._linespacing = other._linespacing
self.stale = True
Expand Down Expand Up @@ -843,6 +859,7 @@ def get_prop_tup(self, renderer=None):
self._verticalalignment, self._horizontalalignment,
hash(self._fontproperties),
self._rotation, self._rotation_mode,
self._transform_rotates_text,
self.figure.dpi, weakref.ref(renderer),
self._linespacing
)
Expand Down Expand Up @@ -1132,6 +1149,17 @@ def set_rotation(self, s):
self._rotation = s
self.stale = True

def set_transform_rotates_text(self, t):
"""
Whether rotations of the transform affect the text direction.

Parameters
----------
t : bool
"""
self._transform_rotates_text = t
self.stale = True

def set_verticalalignment(self, align):
"""
Set the vertical alignment.
Expand Down