Matplotlib 2 mathtext:刻度标签中的字形错误

问题描述 投票:7回答:2

我在使用默认的mathtext而不是LaTeX数学渲染引擎时,在matplotlib 2.0.2中渲染数学时观察到错误。似乎一些字形(在我的情况下是减号和乘号)不能被mathtext识别。真正奇怪的是,只有当这些特定字形出现在刻度标签中时才会出现错误。当我刻意将一些蹩脚的表达式输入到例如图标题,它工作正常。

考虑以下示例和结果图像:

import matplotlib
import matplotlib.pyplot as plt

# Customize matplotlib
matplotlib.rcParams.update({# Use mathtext, not LaTeX
                            'text.usetex': False,
                            # Use the Computer modern font
                            'font.family': 'serif',
                            'font.serif': 'cmr10',
                            'mathtext.fontset': 'cm',
                            })

# Plot
plt.semilogy([-0.03, 0.05], [0.3, 0.05])
plt.title(r'$-6\times 10^{-2}$')
plt.savefig('test.png')

test.png

如图所示,刻度标签中的乘法和一些减号已被其他字符替换。如果我使用LaTeX(通过将'text.usetex'设置为True),一切都很好。为什么会发生这种情况,更重要的是,如何在不将mathtext更改为LaTeX的情况下修复它?

Additional information

这是运行示例代码时打印的警告:

mathtext.py:866: MathTextWarning: Font 'default' does not have a glyph for '\times' [U+d7]
  MathTextWarning)
mathtext.py:867: MathTextWarning: Substituting with a dummy symbol.
  warn("Substituting with a dummy symbol.", MathTextWarning)

请注意,指数中出现的减号会正确呈现。如果我遗漏'mathtext.fontset': 'cm',这些也不会渲染,产生另一个类似的警告:

mathtext.py:866: MathTextWarning: Font 'default' does not have a glyph for '-' [U+2212]
  MathTextWarning)
mathtext.py:867: MathTextWarning: Substituting with a dummy symbol.
  warn("Substituting with a dummy symbol.", MathTextWarning)

此外,如果我在'axes.unicode_minus': False中包含rcParams(并保持'mathtext.fontset': 'cm'),所有减号都会正确呈现,但问题仍然存在于乘法符号上。

在旧版本的matplotlib上,乘法符号错误似乎不是问题(我已经测试过1.5.1,1.4.3和1.3.1)。然而,这些matplotib坚持只生产10-2,1,10 -1,1,10,10 2等刻度标签,因此不需要乘法符号。

python matplotlib unicode latex text-rendering
2个回答
6
投票

我发现STIX字体可以替代现代计算机。

import matplotlib
import matplotlib.pyplot as plt

# Customize matplotlib
matplotlib.rcParams.update(
    {
        'text.usetex': False,
        'font.family': 'stixgeneral',
        'mathtext.fontset': 'stix',
    }
)

# Plot
plt.semilogy([-0.03, 0.05], [0.3, 0.05])
plt.title(r'$-6\times 10^{-2}$')
plt.savefig('test.png')

这会在我的笔记本电脑上产生以下输出:

enter image description here


0
投票

Cause of problem

我现在明白发生了什么。 yticklabels都有类似的格式

r'$\mathdefault{6\times10^{-2}}$'

这适用于主要的刻度标签,其中没有\times10^{-2}部分。我认为这对于小标记标签是失败的,因为\times\mathdefault{}内部不起作用。如here所述,\mathdefault{}用于生成常规(非数学)文本,其字体与用于mathtext的字体相同,但限制的可用符号要少得多。由于\mathdefault{}内部的所有内容都是数学,因此使用\mathdefault{}是完全多余的,因此可以安全地删除它。这解决了这个问题。

Solution

人们可以使用matplotlib的tick formatters来解决这个问题。但是,我想保留默认(次要)刻度标签位置和(预期)格式,因此更简单的解决方案是简单地删除刻度标签的\mathdefault部分:

import warnings
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.mathtext import MathTextWarning

# Customize matplotlib
matplotlib.rcParams.update({# Use mathtext, not LaTeX
                            'text.usetex': False,
                            # Use the Computer modern font
                            'font.family': 'serif',
                            'font.serif': 'cmr10',
                            'mathtext.fontset': 'cm',
                            # Use ASCII minus
                            'axes.unicode_minus': False,
                            })
# Function implementing the fix
def fix(ax=None):
    if ax is None:
        ax = plt.gca()
    fig = ax.get_figure()
    # Force the figure to be drawn
    with warnings.catch_warnings():
        warnings.simplefilter('ignore', category=MathTextWarning)
        fig.canvas.draw()
    # Remove '\mathdefault' from all minor tick labels
    labels = [label.get_text().replace('\mathdefault', '')
              for label in ax.get_xminorticklabels()]
    ax.set_xticklabels(labels, minor=True)
    labels = [label.get_text().replace('\mathdefault', '')
              for label in ax.get_yminorticklabels()]
    ax.set_yticklabels(labels, minor=True)
# Plot
plt.semilogy([-0.03, 0.05], [0.3, 0.05])
plt.title(r'$-6\times 10^{-2}$')
fix()
plt.savefig('test.png')

编写此修复程序的棘手部分是,在绘制图形之前无法获取刻度标签。因此,我们需要先打电话给fig.canvas.draw()。这会引发我已经压制的警告。这也意味着您应该尽可能晚地调用fix(),以便所有轴都像最终一样绘制。最后(正如问题中已经说明的那样),'axes.unicode_minus'已被设置为False以修复与减号相似的问题。

由此产生的图像:test.png敏锐的LaTeX眼睛可能会发现xticklabels中的缺陷仍然略微偏离。这与问题无关,但是因为xticklabels中的数字未包含在$...$中而发生。

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