【问题标题】:Matplotlib 2.0 subscript outside of baseline when super and subscript are both used当同时使用上标和下标时,Matplotlib 2.0 下标超出基线
【发布时间】:2017-06-09 18:46:20
【问题描述】:

在 matplotlib 2.0 中,当我在同一个字符上同时使用下标和上标时,我的行为一直很奇怪。当它们组合在一起时,下标完全低于基线。 MPL 1.5 没有发生这种情况。这是一个完整的例子:

import matplotlib as mpl
import matplotlib.pyplot as plt
mpl.rc("font", family="Times New Roman",weight='normal')
plt.rcParams.update({'mathtext.default':  'regular' })
plt.plot(1,1, label='$A_x^{b}$')
plt.plot(2,2,label='$A_x$')
plt.plot(3,3,label='$A^b$')
plt.plot(4,4,label='$A_x^{*}$')
plt.plot(5,5,label='$A^*$')
plt.legend(fontsize='xx-large')
plt.show()

我拍摄了这张图并放大了图例并绘制了一些水平线以显示相对的上标和下标位置。

我在 mathtext.py 文件中的 FontConstantBase 类下找到了这些参数:

# Percentage of x-height of additional horiz. space after sub/superscripts
script_space = 0.05

# Percentage of x-height that sub/superscripts drop below the baseline
subdrop = 0.4

# Percentage of x-height that superscripts are raised from the baseline
sup1 = 0.7

# Percentage of x-height that subscripts drop below the baseline
sub1 = 0.3

# Percentage of x-height that subscripts drop below the baseline when a
# superscript is present
sub2 = 0.5

# Percentage of x-height that sub/supercripts are offset relative to the
# nucleus edge for non-slanted nuclei
delta = 0.025

# Additional percentage of last character height above 2/3 of the
# x-height that supercripts are offset relative to the subscript
# for slanted nuclei
delta_slanted = 0.2

# Percentage of x-height that supercripts and subscripts are offset for
# integrals
delta_integral = 0.1

sub2 在以前的版本中存在吗?像我看到的那样,从 0.3 到 0.5 真的可以完全降到基线以下吗?我希望同时拥有不完全超出基线的上标和下标,除了修改 mathtext.py 本身之外,我看不到任何其他方式。此外,似乎在上标中包含星号时,它也高于 mpl 2.0 的预期。有没有办法在不改变数学文本的情况下稍微降低它?谢谢。

【问题讨论】:

  • 你能为此创建一个 github 问题吗? (如果尚不存在)

标签: python matplotlib subscript


【解决方案1】:

似乎没有 API 可以改变这一点,但您可以修改适当的类,而不是编辑 mathtext.py

使用默认的 mathtext 字体,如果有上标,下标的位置会发生变化(不完全在基线下,但你可以看到效果):

def test_plot():
    plt.figure()
    plt.plot(1, 1, label="$A_x^b$")
    plt.plot(2, 2, label="$A^b_x$")
    plt.plot(3, 3, label="$A_x$")
    plt.plot(4, 4, label="$A_x^*$")
    plt.plot(4, 4, label="$A^*_x$")
    plt.plot(5, 5, label="$A^*$")
    plt.legend(fontsize="xx-large")


# default mathtext font in matplotlib 2.0.0 is 'dejavusans'
# set explicitly for reproducibility
plt.rcParams["mathtext.fontset"] = "dejavusans"
test_plot()

猴子补丁mathtext.DejaVuSansFontConstants可以让效果消失:

import matplotlib.mathtext as mathtext
mathtext.DejaVuSansFontConstants.sub2 = 0.3  # default 0.5
test_plot()

(对于 matplotlib 的更新版本,如 3.4.2,此类似乎已移至 _mathtext 子模块。您可能需要执行以下操作:)

# Later versions of matplotlib (e.g., 3.4.2)
from matplotlib.mathtext import _mathtext as mathtext

mathtext.FontConstantsBase.sup1 = 0.5

我看不到星号有任何问题。

我没有安装 Times New Roman,所以我无法测试您的确切用例,但您可能需要修补 FontConstantsBase 而不是 DejaVuSansFontConstants。使用 Liberation Serif 对我有用。

【讨论】:

  • 谢谢。这仍然适用于时代吗?我在 mathtext 中看到了 DejaVuSansFontConstants 类,但是当我在 rcparams 中指定该字体时,它是否也为 Times New Roman 创建了一个 FontConstantsBase 对象?有关星号上标的问题,请参见上面的图片。它很高而且在右边。
  • 不确定你的意思。 Times 不是 mathtext.fontset 的有效选项。如果您希望我复制并希望解决您的确切问题,您必须在问题中包含所有相关信息。上标*的位置与上标b的位置一致。
  • @Samwise 提醒您以防万一,因为我在之前的评论中忘记这样做了。
  • 我已更新示例绘图代码以反映我对字体的更改。我的问题是如果我不使用 dejavusans 作为我的 mathtext 字体,如何应用你的“猴子补丁”。在我的示例中,我使用的是 Times New Roman。谢谢。
  • @Samwise 我无法使用 Times New Roman 进行测试,但我添加了一段解释我认为应该如何工作的段落。让我知道它是否适合你。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-22
  • 1970-01-01
  • 2014-04-14
  • 1970-01-01
  • 1970-01-01
  • 2015-06-18
相关资源
最近更新 更多