Matplotlib中线条与文本无法对齐问题求助
Matplotlib旋转文本与线条错位问题
问题描述
尝试通过两点绘制线条,计算线条角度后旋转文本使其与线条匹配,但二者出现错位。代码如下:
import math import numpy as np import matplotlib.pyplot as plt def angle_line(A, B): x = B[0] - A[0] y = B[1] - A[1] angle = math.atan2(y, x ) return angle*180/np.pi fig, ax = plt.subplots() xy_init = (0,0) xy_end = (1, 0.5) # 绘制线条 ax.plot((xy_init[0], xy_end[0]), (xy_init[1], xy_end[1]), color='black', linewidth=0.5, linestyle='--') center = (xy_init[0]+xy_end[0])/2, (xy_init[1]+xy_end[1])/2 angle = angle_line(xy_init, xy_end) # 绘制文本 ax.text(*center, 'TEST', horizontalalignment='center', rotation = angle, verticalalignment='center',fontdict={'fontsize': 20}, color='red')
原因分析
问题出在Matplotlib的rotation参数默认行为:它是基于屏幕坐标系计算旋转角度,而非数据坐标系。当x轴和y轴的像素缩放比例不一致时(比如本例中x轴范围0-1,y轴0-0.5,像素长度不同),你计算的是数据空间里的线条角度,直接传给rotation会导致文本旋转角度与视觉上的线条角度不匹配,从而错位。
解决方法
方法1:启用坐标系旋转适配
修改文本绘制代码,添加rotation_mode='anchor'和transform_rotates_text=True参数,让旋转基于数据坐标系的锚点:
ax.text(*center, 'TEST', horizontalalignment='center', verticalalignment='center', fontdict={'fontsize': 20}, color='red', rotation=angle, rotation_mode='anchor', transform_rotates_text=True)
方法2:计算屏幕空间真实角度
直接将数据坐标转换为屏幕坐标,计算屏幕空间里的线条角度,确保旋转角度完全匹配视觉线条:
# 转换坐标到屏幕空间 display_center = ax.transData.transform(np.array(center)) display_A = ax.transData.transform(np.array(xy_init)) display_B = ax.transData.transform(np.array(xy_end)) dx = display_B[0] - display_A[0] dy = display_B[1] - display_A[1] # 计算屏幕空间角度 screen_angle = np.arctan2(dy, dx) * 180 / np.pi # 绘制文本 ax.text(*center, 'TEST', horizontalalignment='center', verticalalignment='center', fontdict={'fontsize': 20}, color='red', rotation=screen_angle, rotation_mode='anchor')
两种方法都能让文本与线条完美对齐,方法1更简洁,方法2适用于坐标轴缩放变化频繁的场景。
内容的提问来源于stack exchange,提问作者Bruno Mello
相关产品推荐
相关产品推荐

