Python 3.x 当存在多个同名字体时,按族名称设置matplotlib字体
当两者具有相同的名称和特征时,如何告诉Python 3.x 当存在多个同名字体时,按族名称设置matplotlib字体,python-3.x,matplotlib,fonts,Python 3.x,Matplotlib,Fonts,当两者具有相同的名称和特征时,如何告诉matplotlib使用特定的字体变体 例如,我可以告诉matplotlib使用拉丁现代罗马语: #!/usr/bin/env python3 # -*- coding: utf-8 -*- import numpy as np from pathlib import Path import matplotlib as mpl import PyQt5 mpl.use('Qt5Agg') import matplotlib.pyplot as plt
matplotlib
使用特定的字体变体
例如,我可以告诉matplotlib
使用拉丁现代罗马语:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import numpy as np
from pathlib import Path
import matplotlib as mpl
import PyQt5
mpl.use('Qt5Agg')
import matplotlib.pyplot as plt
mpl.rcParams['font.family'] = 'Latin Modern Roman'
mpl.rcParams['font.weight'] = '400'
mpl.rcParams['font.style'] = 'normal'
mpl.rcParams['font.variant'] = 'normal'
mpl.rcParams['mathtext.fontset'] = 'custom'
mpl.rcParams['mathtext.default'] = 'it'
mpl.rcParams['mathtext.rm'] = 'Latin Modern Roman:normal'
mpl.rcParams['mathtext.it'] = 'Latin Modern Roman:italic'
mpl.rcParams['mathtext.bf'] = 'Latin Modern Roman:bold'
mpl.rcParams['xtick.labelsize'] = 8
mpl.rcParams['ytick.labelsize'] = 8
mpl.rcParams['axes.titlesize'] = 10
mpl.rcParams['axes.labelsize'] = 10
x = np.linspace(0,2*np.pi,100)
y = np.sin(x)
fig1 = plt.figure(figsize=(3, 3*(9/16)), dpi=300)
ax1 = fig1.gca()
ax1.plot(x, y, c='r', linewidth=1.0, zorder=20)
ax1.set_xlabel(r'$x\ label$')
ax1.set_ylabel(r'$y\ label$')
fig1.tight_layout(pad=0.15)
plt.show()
好的,很好。但是,如果我想使用拉丁现代罗马语的一个特定的“子样式”呢?例如,在我的系统上,当我通过以下方式列出具有name='Latin Modern Roman'
和weight=400
和style='normal'
和variant='normal'
的可用字体条目时:
fonts = mpl.font_manager.fontManager.ttflist
for f in fonts:
if (f.name=='Latin Modern Roman'):
if all([(f.style=='normal'),(f.weight==400),(f.style=='normal'),(f.variant=='normal')]):
print(f.name)
print(Path(f.fname).stem)
print(f.fname)
print('weight : %s'%str(f.weight))
print('style : %s'%str(f.style))
print('stretch : %s'%str(f.stretch))
print('variant : %s'%str(f.variant))
print('\n')
我得到:
Latin Modern Roman
lmroman9-regular
/usr/share/texmf/fonts/opentype/public/lm/lmroman9-regular.otf
weight : 400
style : normal
stretch : normal
variant : normal
...
...
Latin Modern Roman
lmroman10-regular
/usr/share/texmf/fonts/opentype/public/lm/lmroman10-regular.otf
weight : 400
style : normal
stretch : normal
variant : normal
那么,我如何告诉matplotlib
我想要使用lmroman9 regular.otf
vslmroman10 regular.otf
?在mpl.rcParams
中,我只能指定font.family
、font.weight
、font.style
和font.variant
因此,如果两个.otf
文件具有所有相同的值,我如何告诉它使用一个.otf
?字体之间实际上存在差异,例如:
我已尝试使用matplotlib.FontProperties
实例直接引用.otf
文件,然后重命名它,然后指向新名称,如:
prop = mpl.font_manager.FontProperties(fname='/usr/share/fonts/opentype/lmodern/lmroman10-regular.otf')
prop.set_name('Latin Modern Roman Type 10')
mpl.rcParams['font.family'] = 'Latin Modern Roman Type 10'
但后来我发现找不到findfont:Font-family['Latin-Modern-Roman Type 10']。回到DejaVu Sans。
因为prop.get_name()
仍然(神秘地)返回拉丁现代罗马
而不是拉丁现代罗马类型10
如何告诉matplotlib
我想使用一个而不是另一个
在大多数set\u label
和set\u ticklab
调用中(如本例),可以显式使用fontproperties
指向font\u manager.fontproperties()
实例,但我正在寻找一种通过rcParams
全局设置该实例的方法
注意:我不想在matplotlib
中使用LaTeX
渲染(text.usetex
)
系统:
- Windows 10 Pro 19042上WSL2上的Ubuntu-20.04
- linux上的Python 3.8.5/[GCC 9.3.0]
- matplotlib 3.4.1
这是一个非常好的问题。我将提供我找到该特定问题解决方案的方法。为了复制它,我们首先必须从下载给定的字体(我下载了常规版本10和常规版本17以查看更清晰的区别)。安装后,我们可以通过
matplotlib
检查是否找到新字体:
从matplotlib导入字体管理器
font_manager.font_manager.findSystemFonts(FontText='otf')#Matplotlib与
#.otf扩展还有两个扩展,即“”。ttc'和'.ttf',可以通过
#字体管理器。获取同义词(“otf”)
找到.otf
文件的指定路径后,我们可以使用font\u管理器
将特定版本设置为所选字体
#这将创建一个包含文件的对象,并为其指定自定义名称
#以下是这方面的想法:https://stackoverflow.com/questions/35668219/how-to-set-up-a-custom-font-with-custom-path-to-matplotlib-global-font
fe=font\u manager.FontEntry(
fname='C:\\Users\\\\AppData\\Local\\Microsoft\\Windows\\font\\latin-modern-roman.mroman10-regular.otf',
name='10erLatin')
font_manager.fontManager.ttflist.insert(0,fe)
mpl.rcParams['font.family']=fe.name
让我们把它画出来,以便我们以后可以看到它是否有效
将numpy导入为np
从pathlib导入路径
将matplotlib导入为mpl
#导入PyQt5
#mpl.use('Qt5Agg')#我想内联绘制它;)
将matplotlib.pyplot作为plt导入
mpl.rcParams['font.family']=fe.name
mpl.rcParams['font.weight']='400'
mpl.rcParams['font.style']='normal'
mpl.rcParams['font.variant']='normal'
mpl.rcParams['mathtext.fontset']='custom'
mpl.rcParams['mathtext.default']='it'
mpl.rcParams['mathtext.rm']=fe.name+':normal'
mpl.rcParams['mathtext.it']=fe.name+':斜体'
mpl.rcParams['mathtext.bf']=fe.name+':粗体'
mpl.rcParams['xtick.labelsize']=8
mpl.rcParams['ytick.labelsize']=8
mpl.rcParams['axes.titlesize']=10
mpl.rcParams['axes.labelsize']=10
x=np.linspace(0,2*np.pi,100)
y=np.sin(x)
图1=plt.图(图大小=(3,3*(9/16)),dpi=300)
ax1=图1.gca()
ax1.绘图(x,y,c='r',线宽=1.0,zorder=20)
ax1.set_xlabel(r'$x\label$)
ax1.set_ylabel(r'$y\label$)
图1.紧凑布局(pad=0.15)
plt.show()
让我们将其更改为常规字体的17个版本
fe=font\u manager.FontEntry(
fname='C:\\Users\\\\AppData\\Local\\Microsoft\\Windows\\font\\latin-modern-roman.mroman17-regular.otf',
name='17erLatin')
font_manager.fontManager.ttflist.insert(0,fe)
mpl.rcParams['font.family']=fe.name
同样,让我们绘制它(使用与上面完全相同的代码来创建该绘图,只是预先执行给定的代码)
如果我的后见不算太糟的话,那么文本在全球范围内发生了变化。还有一些其他函数可能很有用,但是,它们实际上隐藏在中。如果遇到问题,请告诉我。您是否尝试过按照中的建议设置
fontproperties=prop
?这在数学模式下不起作用,并且还需要在每个set_label()
和set_ticklebals()
调用中设置fontproperties=prop
,这不方便/不可维护。我正在寻找通过rcParams
全局设置的方法,这正是我想要的!谢谢你,扬尼克!