Matplotlib 图例不考虑 lualatex 的内容大小

问题描述 投票:0回答:1

我需要使用

lualatex
而不是
pdflatex
生成 matplotlib 绘图。除此之外,我使用
fontspec
来更改文档字体。下面我以此为例,将字体设置为
lmroman10-regular.otf
。这会产生一些问题。一是图例中的手柄没有完全居中,并且在右边框之前有一些空白:

A big red arrow point at whitespace after the label text and before the right border of the legend.

生成中间

.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

 文件嵌入到乳胶文档中。似乎不可能直接编译为 
.pdf
,因为文档字体将不是选定的字体,例如可以通过将字体设置为更不同的字体(如 
AntPoltExpd-Italic.otf
)来查看。另请注意,必须在仅限 
\ifluatex
 的代码周围添加 
lualatex
 语句,因为 
matplotlib
 使用 
pdflatex
 来确定文本片段的尺寸,如下所示。

对于这个简单的示例,用于渲染

.tex

.pgf
 文件可能只是:

\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

 进行编译来计算文本块的尺寸。例如,这发生在主分支上相应的 
文件中的
matplotlib.texmanager.TexManager
类中。我想我可以这样解决它: 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

据我了解,这应该会欺骗 matplotlib 认为文本短了 1.14 倍(只是猜测,一旦解决方案有效,就应该进行调整)。该代码肯定会被调用,因为会打印“固定宽度”。但差距并不是固定的:

Nearly the same as the first figure, without the arrow. 如何解决这个问题? matplotlib 如何计算图例内容的宽度,我可以修补它以说明正确的宽度吗?假设我知道字体大小 8 的宽度误差系数约为 1.14。我可以轻松确定其他字体和字体大小。

python matplotlib latex tex pgf
1个回答
0
投票

matplotlib.rcParams["pgf.rcfonts"] = False

否则,如果我理解正确的话,字体设置将从 rcParams 应用。

这解决了您的示例的间距问题:

1 有关更多详细信息,另请参阅

.pgf

后端的 文档,其中解释了此参数。

    

© www.soinside.com 2019 - 2024. All rights reserved.