
先说结论。打印出来字太小,改三处:图在页面里的显示宽度、图里字号、导出分辨率。
但只动字号一定会翻车。我就是这么撞上的 —— 字从 12 号加到 22 号,标注反而开始压顶点圆点、压相邻的字,一团比一团乱。
一开始我以为是图不够清晰
那套相似三角形的题,20 道,图是用脚本画的,插进文档后按页面宽度缩放显示。图里顶点字母设的是 12 号。
用户说字太小看不清。
我第一个反应是分辨率不够。把导出 dpi 从 160 提到 200,重新生成,图还是糊。
问题不在图本身多清晰,在于图有多小。 脚本里的图宽上限写的是 300px。300px 宽的图里塞 12 号字,等于一整张试卷上放了一枚邮票大小的标注。dpi 提得再高,邮票还是邮票,只是邮票上的字更清楚了 —— 它在纸上的物理尺寸没变。
宽度提到 620,字号提到 22,然后开始压
宽度改成 620px,页面正文 17px、题干 19px。字号这一层我分了三个档:顶点字母 22、数值标注 19、图标题 21。
改完一看,图是清楚了。新的问题也来了。
DE 那个标签压在 D 点的圆点上。我把标签往上挪,挪了 30 个点,够不着圆点,改 46,还是压。
然后我意识到自己在干一件蠢事。
我用错了单位
脚本里标签的位置是这么写的 —— 直接在图的坐标上减一个数:
ax.text(midAD[0] - 0.80, midAD[1] - 0.30, f"AD={AD}", fontsize=FS_VALUE)
那个 0.80 和 0.30 是数据单位,也就是「在数学坐标系里往左挪 0.8」。
坐标系里 0.8 是多少像素,取决于这张图的横轴范围和画布宽度。同一个 0.8,横轴范围放大一倍,它代表的像素就少一半。它跟字号根本不是一个量纲的东西。
字号从 12 调到 22,字宽直接涨了八成多,它占据的横向空间跟着涨。而我挪标签用的那个 0.8,纹丝不动。
结果就是字长大了,标签没动,两边就撞上了。
正确写法是用 annotate 加固定点偏移:
ax.annotate(f"DE={DE}", xy=(midDE[0], midDE[1]), xytext=(0, 28),
textcoords="offset points", ha="center", va="bottom",
fontsize=FS_VALUE)
textcoords="offset points" 的意思是「不管坐标系怎么变,我就是要离这个点 28 个点远」。28 个点跟字号 19 是同一个量纲,字怎么改,间距跟着改。

改完还有一个连带问题:AD=3 和 DE=6 同高度撞在一起,DB=2 压住了 D 字母。这是标签都挤在对称轴正上方造成的 —— 点字母挪到点的正下方,数值标签挪到线段下侧,高度错开,才算干净。
改完我拿旧图新图对着一张张看,才想起该先确认一下文件到底改了哪些地方:
grep -n "FS_VERTEX\|FS_VALUE\|FIG_DPI" gen_similar_batch.py
grep -n "max-width:620px" build_similar_sheet.py
ls figs/ | wc -l
现在文件里长这样
三个字号集中在文件开头,后面全部引用常量,不再散落各处:
FS_VERTEX = 22 # 顶点字母 A/B/C/D/E/O
FS_VALUE = 19 # 数值标注(AD=3、DE=9、BC = ?)
FS_TITLE = 21 # 图标题
PAD_TITLE = 28 # 标题与图形顶点的留白(原 18)
LW_EDGE = 2.4 # 主轮廓线宽(原 2.0)
MS_DOT = 7 # 顶点圆点尺寸(原 5)
FIG_DPI = 200 # 导出分辨率(原 160)
留白和线宽是跟着字号一起改的。标题留白从 18 提到 28,轮廓线宽从 2.0 提到 2.4 —— 字大了,线也得压得住,否则细线穿过去字被切一半。
CSS 那边同样改了三处:
h1{font-size:32px}
.stem{font-size:19px}
.qbody img{width:100%;max-width:620px}
以后要再放大,改这七个数就够了,不用去二十个模板里翻。这是中文字体那套坑之外的另一个静默错 —— 字体缺了图会出方块,那是报错能救的;字和间距的单位不对,图照生成、Pillow 和 matplotlib 都不吭声,只能打开看。
改完顺手做的一件事
排版类的东西我不太信自己的眼睛。之前做本地文章编辑器时学到的办法是能查的就别靠看,这次就加了个联系表 —— 一套卷子二三十张图,逐张点开必然偷懒跳过,拼成每张 6 题的联系表,20 题看 4 张就够了。
字号这块还有个坑没解决:图缩到手机上看的时候,620px 的宽度会被压到屏宽以内,19 号的字在手机上还是偏小。移动端标注的粗细粒度该怎么定,我这块没深究,先留着。