各软件中的 pt 有何不同?PDF 查看器、Draw.io 与 LaTeX 的单位陷阱

结论

  • LaTeX 的 pt 是真正的pt(1 pt = 1 / 72.27 inch)
  • PDF 查看器的 pt 实际上是 bp(1bp=1/72inch)
  • Draw.io 中的 pt 实际上是像素(px),默认DPI是100,所以Draw.io pt = 1 px = 1 inch / 100
text 复制代码
1 inch = 25.4 mm
       = 72.27 pt (TeX pt)
       = 72 bp    (PostScript / PDF / Word / matplotlib / MATLAB pt)
       = 100 px   ( Draw.io pt )
单位 用途 转换关系
Scaled Point (sp) DVI 文件内部存储 1 pt = 2¹⁶ sp
TeX Point (pt) TeX 排版系统 1 inch = 72.27 pt
PostScript Point Matplotlib / PDF 1 inch = 72 pt
Pixel 屏幕显示 1 inch = DPI pixels

证明过程如下:

证明1:

  1. \includegraphics[width=1.0\textwidth] 在 LaTeX 中任意插入一张图片,并使用 \typeout{TEXTWIDTH = \the\textwidth} 得到 \textwidth 的值(单位是 pt)
  2. 将 tex 文件编译成 pdf 后使用 WPS 查看,点击编辑后再点击图片就可以看到图片在 WPS 中的宽度(单位是 pt),记为 WPS_width
  3. 求得 textwidthWPS_width≈72.2772\frac{\mathrm{textwidth}}{\mathrm{WPS\_width}}\approx \frac{72.27}{72}WPS_widthtextwidth≈7272.27

证明2:

  1. drawio 绘制并导出为 PDF
    • 图形尺寸:10000 pt * 10000 pt
    • 边框宽度:0 pt
    • 缩放:100%
    • drawio 中,同一个图形,当把单位设为 pt 时,显示为 10000pt * 10000pt,当把单位设为英寸时,显示为 100.000",当把单位设为 mm 时显示为 2540.0mm
    • drawio 中图形尺寸单位 pt 与字体单位 px 相同

证明3:

  1. matplotlib/transforms.py 第 2992-2996 行

    python 复制代码
    if units == 'points':
       x /= 72.0
       y /= 72.0
    # Default units are 'inches'
    return trans + ScaledTranslation(x, y, fig.dpi_scale_trans)
    • 直接定义了 points 单位如何转换为 inches ------ 除以 72.0
  2. matplotlib/backend_pgf.py 第 82-85 行

    python 复制代码
    latex_pt_to_in = 1. / 72.27  # TeX point → inch
    mpl_pt_to_in = 1. / 72.      # Matplotlib point → inch
    • latex_pt_to_in:用于与 LaTeX 交互时,将 TeX point 转换为 inch
    • mpl_pt_to_in:Matplotlib 内部使用,将 PostScript point 转换为 inch
  3. matplotlib/dviread.py 第 303 行

    python 复制代码
    d = self.dpi / (72.27 * 2**16)
    • DVI 文件是 TeX 生成的,使用 TeX 的内部单位(scaled points)
    • 1 TeX point = 2^16 scaled points (sp)
    • 1 TeX point = 1/72.27 inch
    • 所以转换公式:像素 = DPI × (TeX point / inch) / (scaled points / TeX point)
  4. dviread.py 第 593 行

    python 复制代码
    self.size = scale * (72.0 / (72.27 * 2**16))
    • 将 TeX 的 scaled points 转换为 Adobe points(PostScript points)
    • 72.0 / 72.27 就是 TeX point → PostScript point 的转换因子

证明4:

  1. drawio 绘制并导出为 PDF
    • 图形尺寸:10000 pt * 10000 pt
    • 边框宽度:0 pt
    • 缩放:100%
  2. 软件:文档属性显示为
    • WPS:254.068 cm * 254.068 cm,另编辑显示 7200 pt(bp) * 7200 pt(bp)
    • Google Chrome:2541 mm * 2541 mm
    • VSCode:2,540.7 mm * 2,540.7 mm
    • 注:Edge 是例外,其文档属性显示为 3388 mm * 3388 mm,计算约 9603.7795 pt * 9603.7795 pt(bp),这是因为 Edge 使用了微软的默认 DPI(96)

导入到 LaTeX 的修正方法

drawio 绘图导入到 LaTeX 的修正方法:

  • 方法 1 :绘图时人工修正(适用于不指定 width,直接按原始尺寸插入的场景)

    如果你希望 Draw.io 中设定的数值 NNN,在 LaTeX 中不加 width 参数 直接插入时,测量出来的宽度正好也是 NNN TeX pt:

    • 操作 :将图形尺寸、字体大小、线段粗细全都在 Draw.io 里乘以 100 / 72.27(约 1.384)。
    • 原理Draw.io 设定 N×10072.27N \times \frac{100}{72.27}N×72.27100 px →\rightarrow→ 导出 PDF 变为 N×7272.27N \times \frac{72}{72.27}N×72.2772 bp →\rightarrow→ LaTeX 不加缩放直接读取为 NNN TeX pt。
    • 注:如果是导入到 WPS/Word,因为 WPS 使用 bp (1/72 inch),只需将乘数改为 100/72 即可。
    • 注:Draw.io 有两个单位,字体单位是 px,线条粗细、图形尺寸单位是 pt,实际上两者在 Draw.io 内部完全等价 (1 pt = 1 px)。
  • 方法 2 :将错就错,利用 LaTeX 的 width 参数缩放(强烈推荐,全方位无缺点)

    如果你希望所见即所得,即 Draw.io 里设定的图形尺寸、字体大小、线条粗细,在 LaTeX 中显示出来的数值完全一致:

    • 前提条件 :必须保证 Draw.io 中设定的图形总宽度数值 NNN ,恰好等于 LaTeX 中目标宽度的数值 (即 x×\textwidthx \times \texttt{\textbackslash textwidth}x×\textwidth 计算出的 TeX pt 数值)。Draw.io默认 DPI = 100
      例如:若 LaTeX 的 \textwidth 为 400 pt,你使用了 [width=0.5\textwidth],则目标宽度数值为 200。此时你在 Draw.io 中的画布宽度 NNN 就必须设定为 200。
    • 操作 :在 Draw.io 中按真实需求设定尺寸、字体和线宽,导出 PDF 后,在 LaTeX 中使用 \includegraphics[width=x\textwidth]{fig.pdf}
    • 原理
      • Draw.io 导出 PDF 宽度 = Draw.io 设定值 px = Draw.io 设定值 ×72.27100\times \frac{72.27}{100}×10072.27 pt
      • LaTeX 目标宽度=Draw.io 导出 PDF 宽度经过includegraphicswidth=xtextwidth进行一个10072.27的放大\xlongequal{\text{Draw.io 导出 PDF 宽度经过\\includegraphicswidth=x\\\\textwidth进行一个}\frac{100}{72.27}的放大}Draw.io 导出 PDF 宽度经过includegraphicswidth=xtextwidth进行一个72.27100的放大 = Draw.io 设定值 ×72.27100×10072.27\times \frac{72.27}{100} \times \frac{100}{72.27}×10072.27×72.27100 pt = Draw.io 设定值 pt
    • 优点 :因为 LaTeX 的拉伸是全局等比例 的,只要宽度数值对齐,不仅图形总宽度对了,图中的字体大小和线条粗细也会被完美还原Draw.io 中的设定值(单位自动转换为 TeX pt)。完全不需要人工进行复杂的换算。

matplotlib 绘图导入到 LaTeX 的修正方法

  • 方法同上,但是需要注意的是 matplotlib 的图形尺寸figsize单位是英寸,而字体大小fontsize和线宽linewidth单位为 matplotlib pt(即bp)

  • 前提条件 :必须保证 matplotlib 中设定的 figsize 宽度(英寸)×72\times 72×72 ,恰好等于 LaTeX 中目标宽度的数值 (即 x×\textwidthx \times \texttt{\textbackslash textwidth}x×\textwidth 计算出的 TeX pt 数值)。例如:若 LaTeX 的 \textwidth 为 400 pt,你使用了 [width=0.5\textwidth],则目标宽度数值为 200。此时你在 matplotlib 中的 figsize 宽度就必须设定为 200/72≈2.777200 / 72 \approx 2.777200/72≈2.777 英寸。

  • 操作

    1. 在 matplotlib 中按上述公式设定 figsize,并按真实需求设定 fontsizelinewidth
    2. 导出 PDF 后,在 LaTeX 中使用 \includegraphics[width=x\textwidth]{fig.pdf}
  • 原理

    • matplotlib 导出 PDF 宽度 = figsize_width ×72\times 72×72 bp = figsize_width ×72×72.2772\times 72 \times \frac{72.27}{72}×72×7272.27 pt
    • LaTeX 目标宽度=matplotlib 导出 PDF 宽度经过includegraphicswidth=xtextwidth进行一个7272.27的缩小\xlongequal{\text{matplotlib 导出 PDF 宽度经过\\includegraphicswidth=x\\\\textwidth进行一个}\frac{72}{72.27}的缩小}matplotlib 导出 PDF 宽度经过includegraphicswidth=xtextwidth进行一个72.2772的缩小 = figsize_width ×72×72.2772×7272.27\times 72 \times \frac{72.27}{72} \times \frac{72}{72.27}×72×7272.27×72.2772 pt = figsize_width ×72\times 72×72 pt
  • 优点 :只要 figsize 宽度与目标宽度数值对齐,图中的字体大小和线条粗细都会被完美还原为 matplotlib 中的设定值

相关推荐
2601_961845422 小时前
2026四级作文预测26年|英语四级写作范文+模板PDF
java·数据库·spring·eclipse·pdf·tomcat·hibernate
DevOpenClub2 小时前
用 OCR、PDF 转文本和摘要接口构建 RAG 文档入库 Agent
数据库·pdf·ocr
qq_4221525716 小时前
PDF 转 Word 哪个工具好用?2026 年主流方案对比与选型指南
pdf·word
2601_9611940219 小时前
27考研资料|免费全套|电子版
考研·百度·微信·pdf·微信公众平台·facebook·新浪微博
开开心心就好1 天前
清理重复文件释放C盘空间的工具
安全·智能手机·pdf·gitlab·音视频·intellij idea·1024程序员节
2501_930707781 天前
使用C#代码在现有 PDF 文档中添加页眉
pdf
Metaphor6921 天前
使用 Python 旋转 PDF 页面
python·pdf
2601_961194021 天前
考研资料电子版|下载|pdf
java·python·考研·eclipse·django·pdf·pygame
hust_a1 天前
做了一个类似MinerU的pdf解析网站
pdf