使用amsmath和sfmath进行绘图标注的Latex字体样式问题

时间:2014-06-22 11:37:05

标签: python matplotlib latex tex

我有一个与在python中使用TeX相关的问题。

我启用了以下软件包:

import numpy
import matplotlib
import matplotlib.pyplot as plt

matplotlib.rc('text', usetex = True)
matplotlib.rc('font', **{'family' : "sans-serif"})
params = {'text.latex.preamble' : [r'\usepackage{siunitx}', r'\usepackage{sfmath}']}
plt.rcParams.update(params)

可以在我的previous question中查找原因。

但是,我现在也可以使用amsmath包的字体。当我将它包含在params中时,它没有响应。我只需要amsmath就可以用" a"来标记图表的x轴。

所以告诉你我拥有的东西:

enter image description here

和我想要的(关于x标签):

enter image description here

请注意,要生成第二张图片,我将sfmath更改为amsmath。这立即弄乱了x和y-ticks。这是我不想发生的事情。

是否可以将单个字母/单词的字体样式更改为amsmath的字体样式?这样我只能在指示图形的x标签时才使用该字体样式。

另一种方法是在sfmath中将amsmath替换为params,并确保刻度看起来像第一张图片。

由于

在旁注中,数字是使用以下方式创建的:

fig = plt.figure()

ax1 = fig.add_subplot(1, 1, 1)
ax1.set_xlabel(r"$a$", fontsize = 14)

plt.show()

3 个答案:

答案 0 :(得分:8)

我们可以使用您的第二种方法准确地实现您正在寻找的内容:使用amsmath然后将ticklabels更改为不同的字体。这比这里列出的其他答案更具攻击性,但它最能实现你想要的效果。

诀窍是使用amsmath并让Matplotlib像往常一样渲染所有内容,然后在最后,使用原始的sans-serif字体重置刻度标签。我不确定这是否完全颠覆了usetex,但如果确实如此,那么你就会有一些奇怪的TeX渲染标签和Matplotlib渲染标签。看起来很棒!

重要的代码是

fontProperties = {'family':'sans-serif', 'weight': 'normal', 'size': 12}
ax1.set_xticklabels(ax1.get_xticks(), fontProperties)
ax1.set_yticklabels(ax1.get_yticks(), fontProperties)

将此内容添加到脚本末尾并添加amsmath会产生以下结果:

import numpy
import matplotlib
import matplotlib.pyplot as plt

matplotlib.rc('text', usetex = True)
matplotlib.rc('font', **{'family' : "sans-serif"})
params = {'text.latex.preamble' : [r'\usepackage{siunitx}', r'\usepackage{amsmath}']}
plt.rcParams.update(params)

fig = plt.figure(figsize=(8,6))
ax1 = fig.add_subplot(1, 1, 1)
ax1.set_xlabel(r"$a$", fontsize = 14)

fontProperties = {'family':'sans-serif', 'weight': 'normal', 'size': 12}
ax1.set_xticklabels(ax1.get_xticks(), fontProperties)
ax1.set_yticklabels(ax1.get_yticks(), fontProperties)

Figure

答案 1 :(得分:1)

sfmath包有一个选项mathitOrig,它保留了用于斜体数学的原始字体(这是LaTeX中的大部分数学运算)。与$\mathit{a}$一起使用此选项可以为您提供接近您想要的内容,但它并不完美,因为数学字体与amsmath字体不完全相同。

import numpy
import matplotlib
import matplotlib.pyplot as plt

matplotlib.rc('text', usetex = True)
matplotlib.rc('font', **{'family' : "sans-serif"})
params = {'text.latex.preamble' : [r'\usepackage{siunitx}', r'\usepackage[mathitOrig]{sfmath}']}
plt.rcParams.update(params)

fig = plt.figure()
ax1 = fig.add_subplot(1, 1, 1)
ax1.set_xlabel(r"$\mathit{a}$", fontsize = 14)

With matitOrig

答案 2 :(得分:0)

我认为放入$ ... $的所有都会呈现为普通文字。然后我们可以独立定义文本字体和数学字体。但是,刻度标签受LaTeX数学字体的影响,如您的问题所示。这很奇怪,matplotlib以某种方式包装了数学环境中的所有刻度标签。因此,这里的基本挑战是刻度标签以及轴标签使用相同的字体进行渲染。现在,我们可以通过使用多个数学字母来解决这个问题。然后,你必须在整个地方使用\mathrm{}这样的东西。

但是,我的假设是原来的问题是你不喜欢Computer Modern字体中的刻度标签。因此,我的建议是将整体字体更改为看起来很棒的字体,用于刻度标签以及轴标签。我发现Linux Libertine就是这样一种字体。我不是100%肯定matplotlib如何包装文本,因此我建议定义文本和数学字体,两者都很好地配合。这可以通过newtx LaTeX包实现。使用lualatex,前言可以保持非常干净,以实现我们想要的,我们使用现代工具。根据{{​​3}},LuaLaTeX正式支持通过PGF后端生成PDF数据。所以,这是我建议的代码:

import matplotlib as mpl
mpl.use('pgf')
import matplotlib.pyplot as plt

pgf_with_lualatex = {
    "text.usetex": True,
    "pgf.rcfonts": False,   # Do not set up fonts from rc parameters.
    "pgf.texsystem": "lualatex",
    "pgf.preamble": [
        r'\usepackage[libertine]{newtxmath}',
        r'\usepackage[no-math]{fontspec}',
        r'\usepackage{libertine}',
        ]
}
mpl.rcParams.update(pgf_with_lualatex)

fig = plt.figure()
ax1 = fig.add_subplot(1, 1, 1)
ax1.set_xlabel("$a b c$", fontsize = 14)
plt.savefig('figure.pdf')

我们通过将rcfonts设置为False,并在LaTeX前导码中设置文本和数学字体,对字体进行绝对控制。需要no-math包的fontspec选项才能让newtxmath设置数学字体。

制作的PDF看起来不错,这是截图:

enter image description here