Matplotlib中如何实现文本在圆形内精准水平垂直居中?
在Matplotlib中实现圆形内文本的精准水平垂直居中
问题根源
Matplotlib的axis.text()方法中,va="center"是基于**字体基线(baseline)**与字体顶线(ascent)、底线(descent)的中间位置对齐,而非字符的视觉中心。像数字"0"这类无下行部分的字符,其视觉重心高于这个基线中心,就会出现垂直偏移的现象。
通用解决方案
以下方案适配普通数字、组合文本(如(0,0))及TeX复杂标记(如$\mathbf{(0,0)}$):
方案1:基于文本渲染边界的手动校准
通过获取文本实际渲染的边界框,计算视觉中心与当前对齐点的偏移,再调整文本位置,实现精准居中:
from matplotlib import patches import matplotlib.pyplot as plt fig = plt.figure() axis1 = fig.add_subplot(111) plt.axis('off') axis1.set(xlim=[-1,1], ylim=[-1,1], aspect=1) # 添加圆形 smallcircle = patches.Circle(xy=(0,0), radius=0.8, facecolor='g') axis1.add_patch(smallcircle) # 先绘制文本并渲染,获取边界框 text_obj = axis1.text(x=0, y=0, s='0', fontsize=55, ha="center", va="center", color='k') fig.canvas.draw() # 必须执行渲染才能获取准确的边界数据 # 将像素边界转换为数据坐标 bbox_pixel = text_obj.get_window_extent() bbox_data = axis1.transData.inverted().transform(bbox_pixel) # 计算视觉中心与当前y位置的偏移量 current_y = text_obj.get_position()[1] visual_center_y = (bbox_data[0][1] + bbox_data[1][1]) / 2 y_offset = visual_center_y - current_y # 调整文本y坐标 text_obj.set_y(current_y + y_offset) plt.show()
方案2:使用OffsetBox创建自动居中容器
利用matplotlib.offsetbox的组件,自动将文本在容器内视觉居中,无需手动计算偏移:
from matplotlib import patches import matplotlib.pyplot as plt from matplotlib.offsetbox import TextArea, AnnotationBbox fig = plt.figure() axis1 = fig.add_subplot(111) plt.axis('off') axis1.set(xlim=[-1,1], ylim=[-1,1], aspect=1) # 添加圆形 smallcircle = patches.Circle(xy=(0,0), radius=0.8, facecolor='g') axis1.add_patch(smallcircle) # 创建文本区域,支持普通文本或TeX公式 text_area = TextArea('0', textprops={'fontsize':55, 'color':'k'}) # 适配TeX公式的示例:替换为下方代码 # text_area = TextArea(r'$\mathbf{(0,0)}$', textprops={'fontsize':40, 'color':'k'}) # 创建注释框,将文本区域定位在圆心并居中 ab = AnnotationBbox( text_area, (0,0), xycoords='data', boxcoords='data', box_alignment=(0.5, 0.5), # 水平、垂直方向均居中 pad=0, frameon=False ) axis1.add_artist(ab) plt.show()
方案3:快速微调(仅适配固定场景)
如果是固定字符和字体的场景,可以手动微调y坐标并设置va="baseline",但该方法不具备通用性:
axis1.text(x=0, y=-0.03, s='0', fontsize=55, ha="center", va="baseline", color='k')
内容的提问来源于stack exchange,提问作者JSdJ
相关产品推荐
相关产品推荐

