Skip to content

Commit c44db77

Browse files
WiliamQuLogic
Wiliam
authored andcommitted
Fix center of rotation with rotation_mode='anchor'
1 parent c44ae00 commit c44db77

File tree

3 files changed

+30
-4
lines changed

3 files changed

+30
-4
lines changed

lib/matplotlib/backends/backend_agg.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -197,10 +197,20 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
197197
xo, yo = font.get_bitmap_offset()
198198
xo /= 64.0
199199
yo /= 64.0
200-
xd = d * sin(radians(angle))
201-
yd = d * cos(radians(angle))
202-
x = round(x + xo + xd)
203-
y = round(y + yo + yd)
200+
201+
rad = radians(angle)
202+
xd = d * sin(rad)
203+
yd = d * cos(rad)
204+
# Rotating the offset vector ensures text rotates around the anchor point.
205+
# Without this, rotated text offsets incorrectly, causing a horizontal shift.
206+
# Applying the 2D rotation matrix.
207+
rotated_xo = xo * cos(rad) - yo * sin(rad)
208+
rotated_yo = xo * sin(rad) + yo * cos(rad)
209+
# Subtract rotated_yo to account for the inverted y-axis in computer graphics,
210+
# compared to the mathematical convention.
211+
x = round(x + rotated_xo + xd)
212+
y = round(y - rotated_yo + yd)
213+
204214
self._renderer.draw_text_image(font, x, y + 1, angle, gc)
205215

206216
def get_text_width_height_descent(self, s, prop, ismath):

lib/matplotlib/tests/test_text.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,22 @@ def test_alignment():
301301
ax.set_yticks([])
302302

303303

304+
@image_comparison(baseline_images=['rotation_anchor.png'], style='mpl20',
305+
remove_text=True)
306+
def test_rotation_mode_anchor():
307+
fig, ax = plt.subplots()
308+
309+
ax.plot([0, 1], lw=0)
310+
ax.axvline(.5, linewidth=.5, color='.5')
311+
ax.axhline(.5, linewidth=.5, color='.5')
312+
313+
N = 4
314+
for r in range(N):
315+
ax.text(.5, .5, 'pP', color=f'C{r}', size=100,
316+
rotation=r/N*360, rotation_mode='anchor',
317+
verticalalignment='center_baseline')
318+
319+
304320
@image_comparison(['axes_titles.png'])
305321
def test_axes_titles():
306322
# Related to issue #3327

0 commit comments

Comments
 (0)