如何用Matplotlib的TextPath沿任意路径绘制文本及处理文本尺寸问题
在Matplotlib中实现类似SVG
textPath 的沿路径绘文本功能 我想在Matplotlib中实现类似SVG的textPath功能,让文本沿任意路径绘制。已知可以通过子类化Text类实现,但我更倾向于使用TextPath,因为它在绘图域变化时的缩放效果更好。
下面是一个非通用的示例,展示了基本思路:
import numpy as np from matplotlib import pyplot as plt from matplotlib import text as mtext from matplotlib import patches as mpatch from matplotlib import transforms as mtrans fig, ax = plt.subplots(1, 1, figsize=(7, 7), dpi=100) N = 100 cx = -np.cos(np.linspace(0, 2*np.pi, N)) cy = np.sin(np.linspace(0, 2*np.pi, N)) ax.plot(cx, cy, color='black') tpath = mtext.TextPath((0, 0), 'T', .5) tw = tpath.get_extents().width th = tpath.get_extents().height angle = np.rad2deg(np.arctan2(cy[0], cx[0])) tpath = tpath.transformed( mtrans.Affine2D() .translate(-0.5 * tw, -0.5 * th) .rotate_deg(angle - 90) .translate(cx[0], cy[0]) ) tpath2 = mtext.TextPath((0, 0), 'E', .5) tw2 = tpath2.get_extents().width th2 = tpath2.get_extents().height angle2 = np.rad2deg(np.arctan2(cy[5], cx[5])) tpath2 = tpath2.transformed( mtrans.Affine2D() .translate(-0.5 * tw, -0.5 * th) .rotate_deg(angle2 - 90) .translate(cx[5], cy[5]) ) tpath3 = mtext.TextPath((0, 0), 'S', .5) tw3 = tpath3.get_extents().width th3 = tpath3.get_extents().height angle3 = np.rad2deg(np.arctan2(cy[11], cx[11])) tpath3 = tpath3.transformed( mtrans.Affine2D() .translate(-0.5 * tw, -0.5 * th) .rotate_deg(angle3 - 90) .translate(cx[11], cy[11]) ) tpath4 = mtext.TextPath((0, 0), 'T', .5) tw4 = tpath4.get_extents().width th4 = tpath4.get_extents().height angle4 = np.rad2deg(np.arctan2(cy[16], cx[16])) tpath4 = tpath4.transformed( mtrans.Affine2D() .translate(-0.5 * tw, -0.5 * th) .rotate_deg(angle4 - 90) .translate(cx[16], cy[16]) ) tpatch = mpatch.PathPatch(tpath, facecolor='red', edgecolor='black', linewidth=3) tpatch2 = mpatch.PathPatch(tpath2, facecolor='red', edgecolor='black', linewidth=3) tpatch3 = mpatch.PathPatch(tpath3, facecolor='red', edgecolor='black', linewidth=3) tpatch4 = mpatch.PathPatch(tpath4, facecolor='red', edgecolor='black', linewidth=3) ax.add_patch(tpatch) ax.add_patch(tpatch2) ax.add_patch(tpatch3) ax.add_patch(tpatch4) plt.show()

显然,这个示例中的文本间距是硬编码的。要实现通用功能,需要针对任意路径计算文本放置点的角度,同时要准确获取文本尺寸以合理设置间距。我曾考虑子类化TextPath或创建可被TextToPath处理的Path子类,查看源码后发现这些类使用matplotlib._text_helpers模块计算文本尺寸,但不清楚其计算单位(推测为像素,但无文档说明)。希望能得到处理文本尺寸问题的更佳方案,也欢迎分享其他沿曲线路径添加文本的思路。
内容的提问来源于stack exchange,提问作者nawendt
相关产品推荐
相关产品推荐

