Matplotlib:更改数学字体大小,然后恢复默认

7
我从这个问题中学到了如何在matplotlib中更改数学文本的默认大小Matplotlib: 更改数学字体大小。我的做法是:
from matplotlib import rcParams
rcParams['mathtext.default'] = 'regular'

这实际上使LaTeX字体与常规字体大小相同。

我不知道如何将其重置为默认行为,即:LaTeX字体看起来比常规字体小一点。

我需要这样做是因为我希望LaTeX字体在一个图中的外观与常规字体相同,而不是在使用LaTex数学格式的所有图中都相同。

这是我创建图的MWE

import matplotlib.pyplot as plt
import numpy as np
import matplotlib.gridspec as gridspec

# Generate random data.
x = np.random.randn(60)
y = np.random.randn(60)

fig = plt.figure(figsize=(5, 10))  # create the top-level container
gs = gridspec.GridSpec(6, 4)  # create a GridSpec object

ax0 = plt.subplot(gs[0:2, 0:4])
plt.scatter(x, y, s=20, label='aaa$_{subaaa}$')
handles, labels = ax0.get_legend_handles_labels()
ax0.legend(handles, labels, loc='upper right', numpoints=1, fontsize=14)
plt.ylabel('A$_y$', fontsize=16)
plt.xlabel('A$_x$', fontsize=16)

ax1 = plt.subplot(gs[2:4, 0:4])
# I want equal sized LaTeX fonts only on this plot.
from matplotlib import rcParams
rcParams['mathtext.default'] = 'regular'

plt.scatter(x, y, s=20, label='bbb$_{subbbb}$')
handles, labels = ax1.get_legend_handles_labels()
ax1.legend(handles, labels, loc='upper right', numpoints=1, fontsize=14)
plt.ylabel('B$_y$', fontsize=16)
plt.xlabel('B$_x$', fontsize=16)

# If I set either option below the line that sets the LaTeX font as 'regular'
# is overruled in the entire plot.
#rcParams['mathtext.default'] = 'it'
#plt.rcdefaults()

ax2 = plt.subplot(gs[4:6, 0:4])
plt.scatter(x, y, s=20, label='ccc$_{subccc}$')
handles, labels = ax2.get_legend_handles_labels()
ax2.legend(handles, labels, loc='upper right', numpoints=1, fontsize=14)
plt.ylabel('C$_y$', fontsize=16)
plt.xlabel('C$_x$', fontsize=16)

fig.tight_layout()

out_png = 'test_fig.png'
plt.savefig(out_png, dpi=150)
plt.close()

2
你想将所有的 rcParams 重置为默认值吗?如果是的话,请使用 plt.rcdefaults() - Joe Kington
1
或者将默认值 it 放回去。 - Aung
此外,如果您只想要特定的数学公式表达式使用普通字体,而非斜体字,则只需执行 r'$\mathregular{your_expression_here}$' 即可。 - Joe Kington
我已经尝试过 plt.rcdefaults() 和设置 rcParams['mathtext.default'] = 'it',但这两种方法都会给我带来相同的问题:它们要么影响整个图形,要么根本不起作用。让我提供一个更详细的示例来让大家更清楚地了解我的图形设置。 - Gabriel
好的,我已经添加了MWE。请注意,我只想覆盖中间图的默认行为,而不是其他图的行为。 - Gabriel
3个回答

4

我认为这是因为在Axes对象绘制时使用了mathtext.default设置,而不是在创建时使用。为了解决这个问题,我们需要在Axes对象绘制之前改变设置,这里有一个演示:

# your plot code here

def wrap_rcparams(f, params):
    def _f(*args, **kw):
        backup = {key:plt.rcParams[key] for key in params}
        plt.rcParams.update(params)
        f(*args, **kw)
        plt.rcParams.update(backup)
    return _f

plt.rcParams['mathtext.default'] = 'it'
ax1.draw = wrap_rcparams(ax1.draw, {"mathtext.default":'regular'})

# save the figure here

这是输出结果: enter image description here

1
那个解决方案比我想象的要复杂得多 :) 谢谢 @HYRY,我会再等一段时间,如果没有更简单的解决方案被提出,我会将这个标记为已接受。 - Gabriel
不错的答案。将其包装在上下文管理器中,使用with会更加方便(请参见我的下面的答案)。 - Fritz

2
另一种解决方案是更改rcParams设置,强制matplotlib在所有文本中使用tex(我不会尝试解释它,因为我对此设置的理解模糊)。思路是通过设置:
mpl.rcParams['text.usetex']=True

您可以将字符串文字传递给任何(或大多数?)文本定义函数,这些函数将传递给tex,因此您可以使用其大部分(黑色的)魔法。对于这种情况,只需使用\tiny\small\normalsize\large\Large\LARGE\huge\Huge字体大小命令即可。
在您的MWE案例中,只需将第二个散点线更改为:
plt.scatter(x, y, s=20, label=r'bbb{\Huge$_{subbbb}$}')

只有在这种情况下,才能在图例中获得更大的下标字体。其他所有情况都可以直接处理正确。


1
这里有一种优美的Python方式可以临时更改rcParams并自动恢复它们。首先,我们定义一个可与with一起使用的上下文管理器:
from contextlib import contextmanager

@contextmanager
def temp_rcParams(params):
    backup = {key:plt.rcParams[key] for key in params}  # Backup old rcParams
    plt.rcParams.update(params) # Change rcParams as desired by user
    try:
        yield None
    finally:
        plt.rcParams.update(backup) # Restore previous rcParams

然后我们可以使用它来暂时更改一个特定绘图的rcParams:

with temp_rcParams({'text.usetex': True, 'mathtext.default': 'regular'}):
    plt.figure()
    plt.plot([1,2,3,4], [1,4,9,16])
    plt.show()

# Another plot with unchanged options here
plt.figure()
plt.plot([1,2,3,4], [1,4,9,16])
plt.show()

结果:

Two example plots with different fonts


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接