【问题标题】:Matplotlib 2 inconsistent fontMatplotlib 2 字体不一致
【发布时间】:2017-07-04 03:32:07
【问题描述】:

我将 Anaconda Python 更新到最新版本 (4.3),他们将 Matplotlib 升级到版本 2。

升级对默认样式(see here)进行了一些重大更改。 而且,虽然我真的很喜欢其中的一些变化,但我并不同意其中的一些变化。

因此我做了一些修改,如上面链接中的建议:

#%matplotlib inline
#%config InlineBackend.figure_format = 'svg'
import scipy as sc
import matplotlib.pyplot as plt
import matplotlib

# http://matplotlib.org/users/dflt_style_changes.html
params = {'legend.fontsize': 18,
          'axes.labelsize': 18,
          'axes.titlesize': 18,
          'xtick.labelsize' :12,
          'ytick.labelsize': 12,
          'mathtext.fontset': 'cm',
          'mathtext.rm': 'serif',
          'grid.color': 'k',
          'grid.linestyle': ':',
          'grid.linewidth': 0.5,
         }
matplotlib.rcParams.update(params)

x = sc.linspace(0,100)
y = x**2
fig = plt.figure('Fig')
ax = fig.add_subplot(1, 1, 1)
lines = ax.semilogy(x, y)
ax.set_yticks([300], minor=True)
ax.yaxis.grid(True, which='minor')
ax.yaxis.set_minor_formatter(matplotlib.ticker.ScalarFormatter())
ax.tick_params(axis='y', pad=10)
ax.set_xlabel(r'$\mathrm{R_L}$')
ax.set_ylabel(r'$\sigma \int_l \; dx$')
#fig.savefig('./PNG/test.png', dpi=300, bbox_inches='tight')

使用 Latex 作为坐标轴标签,如上面的代码所示,会导致坐标轴上的文字不一致(见下图)。

如何恢复到以前的行为(见下图)或一致的字体方案?

编辑: 使用 Latex 后端我能够得到一个很好的结果,但它非常慢。 无论如何,我认为内部后端应该能够获得一致的输出,并且切换到不同的后端并不是真正的解决方案,而是一种解决方法。

使用 Latex 后端:

#%matplotlib inline
#%matplotlib notebook
#%config InlineBackend.figure_format = 'svg'
import scipy as sc
import matplotlib.pyplot as plt
import matplotlib

# http://matplotlib.org/users/dflt_style_changes.html
params = {'legend.fontsize': 18,
          'axes.labelsize': 18,
          'axes.titlesize': 18,
          'xtick.labelsize' :12,
          'ytick.labelsize': 12,
          'mathtext.fontset': 'cm',
          'mathtext.rm': 'serif',
          'grid.color': 'k',
          'grid.linestyle': ':',
          'grid.linewidth': 0.5,
         }
matplotlib.rcParams.update(params)
matplotlib.rcParams.update({'text.usetex':True, 'text.latex.preamble':[r'\usepackage{amsmath, newtxmath}']})

x = sc.linspace(0,100)
y = x**2
fig = plt.figure('Fig')
ax = fig.add_subplot(1, 1, 1)
lines = ax.semilogy(x, y)
ax.set_yticks([300], minor=True)
ax.yaxis.grid(True, which='minor')
ax.yaxis.set_minor_formatter(matplotlib.ticker.ScalarFormatter())
ax.tick_params(axis='y', pad=10)
ax.set_xlabel(r'$\mathrm{R_L}$')
ax.set_ylabel(r'$\sigma \int_l \; dx$')
#fig.savefig('./PNG/test.png', dpi=300, bbox_inches='tight')

matplotlib 2 的结果是:

与旧版本的结果图是(仍然有点不同,可能是由于一些乳胶差异):

但同样,所需的结果是从旧版本的 matplotlib 获得的结果,如图 2 所示。

【问题讨论】:

  • 您链接到的文档显示“使用内置数学渲染引擎(mathtext)时的默认数学字体已从“Computer Modern”(即 LaTeX-like)更改为“DejaVu Sans” 。”换句话说,default 行为应该是无衬线字体,就像你的底部图表一样。看起来'mathtext.rm': 'serif' 是原因,删除它应该可以解决问题。
  • 我试过这个改变,但输出是一样的。
  • 我无法复制,所以我尝试升级 matplotlib,现在它非常有用地删除了我的 numpy 安装,所以我无法测试任何东西。但是数学字体部分也提到了'mathtext.fontset': 'cm',所以也可以删除它。我不知道那条线是做什么的。
  • 如果我删除它,我会得到所有的 unicode,这是我不喜欢的。我想为乳胶东西和标签保留乳胶字体,但轴号和以前一样(如第二个图所示)。要将 anaconda 更新到我更喜欢从头开始重新安装的最新版本,有时会更好...
  • 我在 Canopy,但如果我有最新的 matplotlib,我会希望它可以重现。但是,我现在在文档中看不到任何清楚说明如何实现这两个目标的内容,所以也许我不想升级,因为它似乎不符合逻辑,没有明确的解决方法。#跨度>

标签: python python-3.x matplotlib


【解决方案1】:

在尝试解决我的问题时,我尝试比较新旧 rcParams 的字典并设置不同且与 mathtext 字体相关的元素:结果非常好。

代码是:

#%matplotlib inline
#%matplotlib notebook
#%config InlineBackend.figure_format = 'svg'
import scipy as sc
import matplotlib.pyplot as plt
import matplotlib

# http://matplotlib.org/users/dflt_style_changes.html
params = {'legend.fontsize': 18,
          'axes.labelsize': 18,
          'axes.titlesize': 18,
          'xtick.labelsize' :12,
          'ytick.labelsize': 12,
          'mathtext.fontset': 'cm',
          'mathtext.rm': 'serif',
          'mathtext.bf': 'serif:bold',
          'mathtext.it': 'serif:italic',
          'mathtext.sf': 'sans\\-serif',
          'grid.color': 'k',
          'grid.linestyle': ':',
          'grid.linewidth': 0.5,
         }
matplotlib.rcParams.update(params)
#matplotlib.rcParams.update({'text.usetex':True, 'text.latex.preamble':[r'\usepackage{amsmath, newtxmath}']})
#matplotlib.rcParams.update({'text.usetex':True, 'text.latex.preamble':[r'\usepackage{amsmath, mathptmx}']})
#matplotlib.rcParams.update({'text.usetex':True, 'text.latex.preamble':[r'\usepackage{amsmath}']})

x = sc.linspace(0,100)
y = x**2
fig = plt.figure('Fig')
ax = fig.add_subplot(1, 1, 1)
lines = ax.semilogy(x, y)
ax.set_yticks([300], minor=True)
ax.yaxis.grid(True, which='minor')
ax.yaxis.set_minor_formatter(matplotlib.ticker.ScalarFormatter())
ax.tick_params(axis='y', pad=10)
ax.set_xlabel(r'$\mathrm{R_L}$')
ax.set_ylabel(r'$\sigma \int_l \; dx$')
fig.savefig('./PNG/test.png', dpi=300, bbox_inches='tight')

因此也添加:

          'mathtext.rm': 'serif',
          'mathtext.bf': 'serif:bold',
          'mathtext.it': 'serif:italic',
          'mathtext.sf': 'sans\\-serif',

导致:

我认为在 Latex 文档中非常好且一致。

另一个answer in this thread from @ImportanceOfBeingErnest也很整洁漂亮。

【讨论】:

    【解决方案2】:

    如果一致性是唯一的问题,您可以使用“Times”字体使用“Roman”样式。没有必要通过usetex 使用 Latex。相反,只需使用 STIX 字体集、Times 字体和衬线数学文本。

    import scipy as sc
    import matplotlib.style
    import matplotlib.pyplot as plt
    
    params = {'legend.fontsize': 18,
              'axes.labelsize': 18,
              'axes.titlesize': 18,
              'xtick.labelsize' :12,
              'ytick.labelsize': 12,
              'grid.color': 'k',
              'grid.linestyle': ':',
              'grid.linewidth': 0.5,
              'mathtext.fontset' : 'stix',
              'mathtext.rm'      : 'serif',
              'font.family'      : 'serif',
              'font.serif'       : "Times New Roman", # or "Times"          
             }
    matplotlib.rcParams.update(params)
    
    x = sc.linspace(0,100)
    y = x**2
    fig = plt.figure('Fig')
    ax = fig.add_subplot(1, 1, 1)
    lines = ax.semilogy(x, y)
    
    ax.yaxis.set_minor_formatter(matplotlib.ticker.ScalarFormatter())
    ax.tick_params(axis='y', pad=10)
    ax.set_yticks([300], minor=True)
    ax.yaxis.grid(True, which='minor')
    ax.set_xlabel(r'$\mathrm{R_L}$')
    ax.set_ylabel(r'$\sigma \int_l \; dx$')
    plt.tight_layout()
    plt.show()
    

    【讨论】:

    • 整洁,输出很好且一致。同时我尝试比较 rcParam 的字典并尝试设置不同的元素:结果非常好。我会尽量把这个作为可能的答案给自己(不接受我自己的答案,因为我不觉得它是确定的)。
    【解决方案3】:

    从您提供的链接中:

    提供了一个“经典”样式表,因此恢复到 1.x 的默认值只需一行 python

    mpl.style.use('经典')

    添加这一行

    matplotlib.style.use('classic')
    

    到你的脚本应该可以解决你的问题。

    我在我的 python2.7/matplotlib 2 上对其进行了测试,它运行良好(即我取回了 matplotlib 1.x 字体)。

    【讨论】:

    • 是的,但它确实是老式风格。您没有获得与第二个情节相同的风格。我想保留新样式并修复字体问题。
    • @Alex:我以为你的意思只是轴刻度。有关字体的更多详细信息,请参阅matplotlib.org/users/mathtext.html#fonts。将您的代码更改为 'mathtext.fontset': 'stixsans', 和/或 'mathtext.rm': 'sansserif', 对我来说会产生非常好的结果。
    • 但是标签里的latex字体不一样,很丑。
    猜你喜欢
    • 2016-02-29
    • 2021-10-15
    • 2012-07-07
    • 2017-07-09
    • 2018-02-17
    • 1970-01-01
    • 1970-01-01
    • 2012-08-15
    • 1970-01-01
    相关资源
    最近更新 更多