You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用LuaLaTeX渲染Matplotlib图例时右侧出现多余空白、尺寸不匹配的问题修复咨询

使用LuaLaTeX渲染Matplotlib图例时右侧出现多余空白、尺寸不匹配的问题修复咨询

我现在遇到这么个棘手的问题:用lualatex替代pdflatex渲染Matplotlib生成的图时,图例里的标记没法完全居中,而且标签文字右侧到图例边框之间总是有多余的空白,效果如下:

图例右侧多余空白,红色箭头指向空白区域

生成中间.pgf文件的Python代码是这样的:

import matplotlib
import numpy

from matplotlib import pyplot

x = numpy.linspace(-1, 1)
y = x ** 2

matplotlib.rcParams["figure.figsize"] = (3, 2.5)
matplotlib.rcParams["font.family"] = "serif"
matplotlib.rcParams["font.size"] = 10
matplotlib.rcParams["legend.fontsize"] = 8
matplotlib.rcParams["pgf.texsystem"] = "lualatex"

PREAMBLE = r"""\usepackage{ifluatex}
\ifluatex
\usepackage{fontspec}
\setmainfont{lmroman10-regular.otf}
\fi
"""

matplotlib.rcParams["text.latex.preamble"] = PREAMBLE
matplotlib.rcParams["pgf.preamble"] = PREAMBLE
matplotlib.rcParams["text.usetex"] = True

pyplot.plot(x, y, label="this is the data")
pyplot.legend()
pyplot.xlabel("xlabel")
pyplot.tight_layout()
pyplot.savefig("lualatex_test.pgf")

之后我把这个.pgf文件嵌入LaTeX文档,简单的示例文档代码如下:

\documentclass[11pt]{scrbook}
\usepackage{pgf}
\usepackage{fontspec}
\setmainfont{lmroman10-regular.otf}
\newcommand{\mathdefault}[1]{#1}
\begin{document}
\input{lualatex_test.pgf}
\end{document}

用lualatex <filename>编译后就会出现上面图里的问题(不带红色箭头的版本)。

我本来猜测问题根源是:Matplotlib计算文本尺寸时用的是pdflatex,但实际渲染用的是lualatex,两种引擎对同一字体的尺寸计算有差异。于是我尝试修改TexManager.get_text_width_height_descent方法,手动调整文本宽度:

class TexManager:
    # 其他原有代码...

    @classmethod
    def get_text_width_height_descent(cls, tex, fontsize, renderer=None):
        """Return width, height and descent of the text."""
        if tex.strip() == '':
            return 0, 0, 0
        dvifile = cls.make_dvi(tex, fontsize)
        dpi_fraction = renderer.points_to_pixels(1.) if renderer else 1
        with dviread.Dvi(dvifile, 72 * dpi_fraction) as dvi:
            page, = dvi
        # A total height (including the descent) needs to be returned.
        w = page.width
        # 手动调整宽度的尝试
        if tex == "this is the data":
            w /= 1.14
            print("fixed width")
        # 结束调整
        return w, page.height + page.descent, page.descent

代码确实被调用了——控制台打印出了"fixed width",但空白问题还是没解决,效果如下:

修改后仍存在的空白

想请教一下:怎么才能彻底修复这个问题?Matplotlib到底是怎么计算图例内容宽度的?有没有办法通过补丁来修正宽度,比如我已经知道字号8时宽度误差大概是1.14倍,其他字体和字号也可以确定对应的系数。

备注:内容来源于stack exchange,提问作者HerpDerpington

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 14:17:58