Skip to content

Commit 4e11730

Browse files
authored
Merge pull request #15532 from immaxchen/text-rotation-can-get-transformed-too-gh698
Resolve 'text ignores rotational part of transformation' (#698)
2 parents 74fdc27 + 46c2791 commit 4e11730

File tree

4 files changed

+50
-5
lines changed

4 files changed

+50
-5
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
:orphan:
2+
3+
Transform can rotate text direction
4+
-----------------------------------
5+
The new `.Text` parameter ``transform_rotates_text`` now sets whether
6+
rotations of the transform affect the text direction.
7+

examples/text_labels_and_annotations/text_rotation_relative_to_line.py

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

1717
import matplotlib.pyplot as plt
@@ -31,12 +31,12 @@
3131

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

3635
# Plot text
3736
th1 = ax.text(*l1, 'text not rotated correctly', fontsize=16,
3837
rotation=angle, rotation_mode='anchor')
3938
th2 = ax.text(*l2, 'text rotated correctly', fontsize=16,
40-
rotation=trans_angle, rotation_mode='anchor')
39+
rotation=angle, rotation_mode='anchor',
40+
transform_rotates_text=True)
4141

4242
plt.show()

lib/matplotlib/tests/test_text.py

+10
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from matplotlib.backend_bases import MouseEvent
1111
import matplotlib.patches as mpatches
1212
import matplotlib.pyplot as plt
13+
import matplotlib.transforms as mtransforms
1314
from matplotlib.testing.decorators import check_figures_equal, image_comparison
1415

1516

@@ -689,3 +690,12 @@ def test_fontproperties_kwarg_precedence():
689690
text2 = plt.ylabel("counts", size=40.0, fontproperties='Times New Roman')
690691
assert text1.get_size() == 40.0
691692
assert text2.get_size() == 40.0
693+
694+
695+
def test_transform_rotates_text():
696+
ax = plt.gca()
697+
transform = mtransforms.Affine2D().rotate_deg(30)
698+
text = ax.text(0, 0, 'test', transform=transform,
699+
transform_rotates_text=True)
700+
result = text.get_rotation()
701+
assert_almost_equal(result, 30)

lib/matplotlib/text.py

+29-1
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ def __init__(self,
136136
rotation_mode=None,
137137
usetex=None, # defaults to rcParams['text.usetex']
138138
wrap=False,
139+
transform_rotates_text=False,
139140
**kwargs
140141
):
141142
"""
@@ -157,6 +158,7 @@ def __init__(self,
157158
self.set_horizontalalignment(horizontalalignment)
158159
self._multialignment = multialignment
159160
self._rotation = rotation
161+
self._transform_rotates_text = transform_rotates_text
160162
self._bbox_patch = None # a FancyBboxPatch instance
161163
self._renderer = None
162164
if linespacing is None:
@@ -228,7 +230,20 @@ def _get_multialignment(self):
228230

229231
def get_rotation(self):
230232
"""Return the text angle in degrees between 0 and 360."""
231-
return get_rotation(self._rotation) # string_or_number -> number
233+
if self.get_transform_rotates_text():
234+
angle = get_rotation(self._rotation)
235+
x, y = self.get_unitless_position()
236+
angles = [angle, ]
237+
pts = [[x, y]]
238+
return self.get_transform().transform_angles(angles, pts).item(0)
239+
else:
240+
return get_rotation(self._rotation) # string_or_number -> number
241+
242+
def get_transform_rotates_text(self):
243+
"""
244+
Return whether rotations of the transform affect the text direction.
245+
"""
246+
return self._transform_rotates_text
232247

233248
def set_rotation_mode(self, m):
234249
"""
@@ -259,6 +274,7 @@ def update_from(self, other):
259274
self._fontproperties = other._fontproperties.copy()
260275
self._usetex = other._usetex
261276
self._rotation = other._rotation
277+
self._transform_rotates_text = other._transform_rotates_text
262278
self._picker = other._picker
263279
self._linespacing = other._linespacing
264280
self.stale = True
@@ -835,6 +851,7 @@ def get_prop_tup(self, renderer=None):
835851
self._verticalalignment, self._horizontalalignment,
836852
hash(self._fontproperties),
837853
self._rotation, self._rotation_mode,
854+
self._transform_rotates_text,
838855
self.figure.dpi, weakref.ref(renderer),
839856
self._linespacing
840857
)
@@ -1124,6 +1141,17 @@ def set_rotation(self, s):
11241141
self._rotation = s
11251142
self.stale = True
11261143

1144+
def set_transform_rotates_text(self, t):
1145+
"""
1146+
Whether rotations of the transform affect the text direction.
1147+
1148+
Parameters
1149+
----------
1150+
t : bool
1151+
"""
1152+
self._transform_rotates_text = t
1153+
self.stale = True
1154+
11271155
def set_verticalalignment(self, align):
11281156
"""
11291157
Set the vertical alignment.

0 commit comments

Comments
 (0)