欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

一文彻底解决 matplotlib 中的字体管理

程序员文章站 2022-06-27 14:14:49
一文彻底解决 matplotlib 中的字体管理如果根据本文,在windows, matplotlib, python 中遇到字体的问题仍然不能自己解决,我先投降!!!使用 matplotlib 可视化数据时,经常要面对字体设置的问题。在要用到中文时,如果设置不当,会出现乱码。网上已经有很多文章提供了一些解决方法,但多数是片段式的“授人以鱼”,本文将系统地讨论 matplotlib 中的字体管理,希望能“授人以渔”。环境:Windows 10 + anaconda (python 3.8.3) + m...

一文彻底解决 matplotlib 中的字体管理

如果根据本文,在windows, matplotlib, python 中遇到字体的问题仍然不能自己解决,我先投降!!!

使用 matplotlib 可视化数据时,经常要面对字体设置的问题。在要用到中文时,如果设置不当,会出现乱码。网上已经有很多文章提供了一些解决方法,但多数是片段式的“授人以鱼”,本文将系统地讨论 matplotlib 中的字体管理,希望能“授人以渔”。

环境:Windows 10 + anaconda (python 3.8.3) + matplotlib 3.3.1

如果你的环境不同,相关程序安装位置不同,一些细节,如路径、数量等可能会有一些差异,但“对应”到你的环境即可。

matplotlib 中使用的字体来源于三个途径:

  1. matplotlib 自带的字体;
  2. windows 系统字体;
  3. 用户提供的第三方字体。

注意

  1. 实际中不建议调用用户字体目录中的第三方字体文件;
  2. 有很多特殊的字体不兼容,会报错

windows 10 系统字体

windows 字体文件的位置

Windows 系统字体文件保存在 C:\Windows\Fonts 文件夹中,在资源管理器中打开这个文件夹,一般是以大图标的形式显示,看起来是这样的:

图 1:
一文彻底解决 matplotlib 中的字体管理
注意: 它与浏览一般的文件夹不同。这里打开的实际是 windows 字体管理器,它提供了Windows字体管理的功能。

我们从 windows 控制面板中打开字体管理器,比较一下就清楚了:

图2:
一文彻底解决 matplotlib 中的字体管理
里面的图标有两类:

  • 单页,表示这是单个字体文件;
  • 多页,表示这是一个字体系列,里面有多个字体文件。

参见图1 的标注。

图3:字体系列,相当于一个子文件夹,可以进一步打开

一文彻底解决 matplotlib 中的字体管理
我的 C:\Windows\Fonts 文件夹下有672个字体文件:

图4:

一文彻底解决 matplotlib 中的字体管理

windows 字体的详细属性

将Fonts文件夹的浏览模式设置为“详细信息”视图:

图5:
一文彻底解决 matplotlib 中的字体管理
并且选择显示“字体文件名称”属性:

图6:
一文彻底解决 matplotlib 中的字体管理
在 windows 中,字体是以“字体文件”的形式保存的,但在应用软件中为了调用的直观性和方便性,则是通过字体的“名称”属性来调用的。如 office 中。

注意: 区分字体的 “名称” 与字体的 “字体文件名称”
一文彻底解决 matplotlib 中的字体管理

Python 读取 Windows 系统“字体文件名称”

下面的代码会打印出 C:\Windows\Fonts文件夹中 “字体文件名称”。

import os, sys, winreg

font_files = os.listdir(r'C:\Windows\Fonts')

print("字体文件数:  ",len(font_files))

# for i in fontfiles: 打印全部系统字体文件的列表
for i in font_files[20:30]: 
    print(i)
字体文件数:   672
85f874.fon
85s1255.fon
85s1256.fon
85s1257.fon
85s874.fon
AGENCYB.TTF
AGENCYR.TTF
ALGER.TTF
ANTQUAB.TTF
ANTQUABI.TTF

读取的字体文件数 672 个,与图4中 Fonts文件夹属性显示的文件数一致。

有很多字体是系统专用字体,在资源管理器中,或控制面板的字体管理器中,看不到它们,系统做了隐藏和保护。 在应用软件中也只有部分字体可用。

我的 Fonts 文件夹中,可见的字体文件(含系列)是 308个:
一文彻底解决 matplotlib 中的字体管理

字体文件的类型和字体类型

字体文件格式和字体类型繁多,常见的有:

字体文件:.TTF, .FON, .TTC, .AFM等后缀(格式)。

字体类型:OpenType, TrueType, 光栅 等类型。

光栅字体(.FON)

这种字体是针对特定的显示分辨率以不同大小存储的位图,用于Windows系统中屏幕上的菜单、按钮等处文字的显示。它并不是以矢量描述的,放大以后会出现锯齿,只适合屏幕描述。不过它的显示速度非常快,所以作为系统字体而在Windows中使用。

矢量字体(.FON)

虽然扩展名和光栅字体一样,但是这种字体却是由基于矢量的数学模型定义的,是Windows系统字体的一类,一些windows应用程序会在较大尺寸的屏幕显示中自动使用矢量字体来代替光栅字体的显示。

.fon 字体文件其实是标准的windows可执行文件(.exe)格式,分NE(New Executable)PE(Portable Executable)两种类型,字体作为资源存在其中。

TrueType字体(.TTF)

TrueType是由美国苹果公司和微软公司共同开发的一种电脑轮廓字体(曲线描边字)类型标准。这是我们日常操作中接触得最多的一种类型的字体,其最大的特点就是它是由一种数学模式来进行定义的基于轮廓技术的字体,这使得它们比基于矢量的字体更容易处理,保证了屏幕与打印输出的一致性。同时,这类字体和矢量字体一样可以随意缩放、旋转而不必担心会出现锯齿

OpenType 也叫 Type 2 字体,是由 Microsoft 和 Adobe 公司开发的另外一种字体格式。它也是一种轮廓字体,比TrueType更为强大,最明显的一个好处就是可以在把PostScript字体嵌入到TrueType的软件中。并且还支持多个平台,支持很大的字符集,还有版权保护。可以说它是 Type 1 和 TrueType 的超集。

OpenType标准还定义了 OpenType 文件名称的后缀名。包含 TrueType 字体的OpenType文件后缀名为.ttf,包含PostScript字体的文件后缀名为.OTF。如果是包含一系列TrueType字体的字体包文件,那么后缀名为.TTC

.AFM Adobe Font Metrics

这由Adobe公司开发,并包含了有关Type 1 PostScript 字体的度量特性的信息。AFM结构需要一个定义了每一个字体符号的样式的控制模版。它主要被用于UNIX。

python 读取可用字体的“名称”

#需要用到 wxPython 库

import wx

from wx import FontEnumerator

aaa = wx.App(False)

# FontEnumerator 枚举系统上所有可用的字体
e = wx.FontEnumerator()

fontlist=e.GetFacenames()

print("可用字体数:", len(fontlist))

for i in fontlist[:20]:
    print(i)
可用字体数: 424
System
@System
Terminal
@Terminal
Fixedsys
@Fixedsys
Modern
Roman
Script
Courier
MS Serif
MS Sans Serif
Small Fonts
Adobe Devanagari
Source Sans Pro Black
Marlett
Arial
Arial Black
Bahnschrift Light
Bahnschrift SemiLight

windows 字体“名称” 到 “字体文件名称”的映射

系统中的字体是以字体文件存在的,而在应用程序中则是通过字体的“名称”调用字体的,Windows 是通过注册表来实现映射和调用的,在注册表的如下位置注册了字体名称到字体文件的映射:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts]

我导出了一个系统字体名称到文件名称映射关系的 txt 文件,共有486个键值对,即486个字体文件,这些是一般用户可以调用的系统字体。

需要的可以到python草堂中 457079928 下载。

一文彻底解决 matplotlib 中的字体管理

python 读取注册表注册的字体名称和对应的文件名称

下面的代码读取 Windows 注册表中注册的字体名称和对应的文件名。

枚举CurrentVersion\fonts下的字体键值对

# -*- coding: utf-8 -*-
# coding:utf-8

import sys
from winreg import *


def get_reg_fonts():
    # 1.连接注册表根键,HKEY_LOCAL_MACHINE
    regRoot = ConnectRegistry(None, HKEY_LOCAL_MACHINE)
    #regRoot = r'HKEY_LOCAL_MACHINE'
    
    subDir = r'SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts'
    
    #reg query "\\RemoteMachineName\HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion" /v BuildLabEx
        
    # 2.获取指定目录下所有键的控制(可用于遍历)
    keyHandle = OpenKey(regRoot, subDir, 0, winreg.KEY_QUERY_VALUE)

    # 获取该目录下所有键的个数(0-下属键个数; 1-当前键值个数)
    count_key = QueryInfoKey(keyHandle)[1]
    print(count_key)

    # 获取该键的所有键值,遍历枚举
    try:
        i = 0
        while 1:  # while True:
            # EnumKey用来枚举子键,EnumValue方法用来枚举键值,
            name, value, type1 = winreg.EnumValue(keyHandle, i)
            print(repr(name), value)

            return value  # 注销即可打印注册表注册的全部字体名称和字体文件名
            i += 1
            
        CloseKey(keyHandle)
        CloseKey(regRoot)

    except WindowsError:
        print('error')
        
        if keyHandle:
            winreg.CloseKey(keyHandle)

if __name__ == '__main__':
    get_reg_fonts()
486
'Arial (TrueType)' arial.ttf

先获取键下的值个数,再遍历值

from winreg import *
import sys

# 1.连接注册表根键,HKEY_LOCAL_MACHINE
regRoot = ConnectRegistry(None, HKEY_LOCAL_MACHINE)
    
#regRoot = r'HKEY_LOCAL_MACHINE'
subDir = r'SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts'    
      
# 2.获取指定目录下所有键的控制(可用于遍历)
keyHandle = OpenKey(regRoot, subDir, 0, winreg.KEY_QUERY_VALUE)

# 获取该目录下所有键的个数(0-下属键个数; 1-当前键值个数)
count_key = QueryInfoKey(keyHandle)[1]
print(count_key)

key_list = []
for i in range(count_key):
    name, key_value, value_type = winreg.EnumValue(keyHandle, i)
    key_list.append((name, key_value))


#for k in range(len(key_list)):
for k in range(20):
    print(key_list[k])
    #print(key_list[k][0]) #仅打印 name,

if keyHandle:
    winreg.CloseKey(keyHandle)
486
('Arial (TrueType)', 'arial.ttf')
('Arial Black (TrueType)', 'ariblk.ttf')
('Arial Bold (TrueType)', 'arialbd.ttf')
('Arial Bold Italic (TrueType)', 'arialbi.ttf')
('Arial Italic (TrueType)', 'ariali.ttf')
('Bahnschrift (TrueType)', 'bahnschrift.ttf')
('Calibri (TrueType)', 'calibri.ttf')
('Calibri Bold (TrueType)', 'calibrib.ttf')
('Calibri Bold Italic (TrueType)', 'calibriz.ttf')
('Calibri Italic (TrueType)', 'calibrii.ttf')
('Calibri Light (TrueType)', 'calibril.ttf')
('Calibri Light Italic (TrueType)', 'calibrili.ttf')
('Cambria & Cambria Math (TrueType)', 'cambria.ttc')
('Cambria Bold (TrueType)', 'cambriab.ttf')
('Cambria Bold Italic (TrueType)', 'cambriaz.ttf')
('Cambria Italic (TrueType)', 'cambriai.ttf')
('Candara (TrueType)', 'candara.ttf')
('Candara Bold (TrueType)', 'candarab.ttf')
('Candara Bold Italic (TrueType)', 'candaraz.ttf')
('Candara Italic (TrueType)', 'candarai.ttf')

matplotlib 字体管理

matplotlib 的matplotlib.font_manager 模块,用于跨平台查找、管理和使用字体。

这个模块提供了一个可以跨后端(backend)和平台共享的 FontManager 实例。其中的 findfont 函数在返回本地或系统字体路径中与指定的 FontPropeties 实例匹配的最佳 TrueType (TTF) 字体文件。FontManager还处理 PostScript 后端使用的 Adobe Font Metrics (AFM) 字体文件。

也就是说 matplotlib 主要处理和使用 TTF, AFM 两种字体。

字体文件可以保存在 matplotlib 的 fonts 文件夹下,也可以保存在系统字体路径中。

matplotlib 的字体文件夹路径如下:

C:\Anaconda3\envs\py38env\Lib\site-packages\matplotlib\mpl-data\fonts

该文件夹下有三个子文件夹,保存的都是 TTF, AFM 格式的字体文件。其中的 ttf 文件夹中约有 40 个 TTF 字体文件。

打开 matplotlib 的 .fonts/ttf 文件夹,与 windows 系统字体文件夹不同,这里没有“字体文件名称”属性,而是“文件名称”。且字体的“名称” 与“文件名称”一致。 请注意这种差别

一文彻底解决 matplotlib 中的字体管理

matplotlib的 font_manager 模块

matplotlib font_manager模块的 UML 图:
一文彻底解决 matplotlib 中的字体管理
font_manager 模块主要设计了3个类:

  • .FontEntry,
  • .FontManager,
  • .FontProperties, 这个是一般用户最常用的类。

.FontEntry 类

class matplotlib.font_manager.FontEntry(fname='', name='', style='normal', variant='normal', weight='normal', stretch='normal', size='medium')

.FontEntry 类实例用一个字典存储字体的属性:


def __init__(self,
                 fname  ='',
                 name   ='',
                 style  ='normal',
                 variant='normal',
                 weight ='normal',
                 stretch='normal',
                 size   ='medium',
                 ):

下面是一个存了 simhei.ttf 字体属性的 FontEntry 实例:

{
    "fname": "C:\\Windows\\Fonts\\simhei.ttf",
    "name": "SimHei",
    "style": "normal",
    "variant": "normal",
    "weight": 400,
    "stretch": "normal",
    "size": "scalable",
    "__class__": "FontEntry"
},

使用 FontEntry 类

FontEntry 主要供 matplotlib 平台管理、存储可用字体属性使用。

我们可以用它来统一出版物中 matplotlib 绘图的字体,减少多图中字体设置的重复劳动,请看下面的示例:

%matplotlib inline

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.font_manager as fm

# 创建一个 FontEntry 实例,统一用于 axes_titlef
axes_titlef = fm.FontEntry(fname='STXINGKA.TTF', name='STXingkai', style='italic',size=20)

# 创建一个 FontEntry 实例,统一用于 axis_titlef
# 请注意,这里调用了用户字体目录中的字体文件,实际中不要这样用
# 有很多特殊的字体不兼容,会报错
#axis_labelf = fm.FontEntry(fname='D:\my_fonts\SIMYOU',name='YouYuan',size=12)
#方正小标宋简体,的 name=`FZXiaoBiaoSong-B05S`
axis_labelf = fm.FontEntry(fname='D:\my_fonts\方正小标宋简体.ttf',name='FZXiaoBiaoSong-B05S',size=12)


x = np.arange(0, 10, 0.2)
y = np.sin(x)


fig = plt.figure(constrained_layout=True)

ax = fig.add_subplot(111)

# 可以重复调用 FontEntry 实例
ax.set_title('轴标题', fontname=axes_titlef.name, fontsize=axes_titlef.size)
ax.set_xlabel('x-轴标签', fontname=axis_labelf.name, fontsize=axis_labelf.size)

ax.plot(x,y)

plt.show()

一文彻底解决 matplotlib 中的字体管理

FontManager 类

FontManager 类提供了字体管理功能。

导入时,FontManager 单例实例创建一个 ttf 和 afm 字体列表,并缓存它们的字体属性。FontManager.findfont方法执行最近邻搜索,以查找最符合规范的字体。如果没有找到足够好的匹配,则返回默认字体。

安装 matplotlib库时,font_manager模块生成一个fontlist-v310.json文件,路径为C:\Users\系统用户名\.matplotlib,

该文件有:

  • 一个字典;
  • 一个afmlist列表;
  • 一个ttflist列表。

这个文件中存有可用字体的名称(包括系统内的本地字体),而可调用的字体的名称并非字体文件的名称,所以需根据需求在文件中查询所需更改字体的名称。

fontlist-v310.json文件开始的字典保存了 matplotlib 默认字体设置:

{
  "_version": 330,
  "_FontManager__default_weight": "normal",
  "default_size": null,
  "defaultFamily": {
    "ttf": "DejaVu Sans",
    "afm": "Helvetica"
  }

afmlist, ttflist 列表保存了所有可用的字体的 FontEntry 实例,每个字体一个 FontEntry 属性字典:

"afmlist": [
    {
      "fname": "fonts\\afm\\ptmb8a.afm",
      "name": "Times",
      "style": "normal",
      "variant": "normal",
      "weight": "bold",
      "stretch": "normal",
      "size": "scalable",
      "__class__": "FontEntry"
    },
    
    ......
    
"ttflist": [
    {
      "fname": "fonts\\ttf\\cmex10.ttf",
      "name": "cmex10",
      "style": "normal",
      "variant": "normal",
      "weight": 400,
      "stretch": "normal",
      "size": "scalable",
      "__class__": "FontEntry"
    },
    ......   

matplotlib 就是从这里检索字体及其属性使用的。
一文彻底解决 matplotlib 中的字体管理

创建一个 FontManager 类实例

import matplotlib.font_manager as fm

mf = fm.FontManager(size=16)
Matplotlib is building the font cache; this may take a moment.
print(mf.defaultFamily, '\n', mf.defaultFont, '\n',mf.default_size)
{'ttf': 'DejaVu Sans', 'afm': 'Helvetica'} 
 {'ttf': 'C:\\Anaconda3\\envs\\py38env\\Lib\\site-packages\\matplotlib\\mpl-data\\fonts\\ttf\\DejaVuSans.ttf', 'afm': 'C:\\Anaconda3\\envs\\py38env\\Lib\\site-packages\\matplotlib\\mpl-data\\fonts\\pdfcorefonts\\Helvetica.afm'} 
 16
mf.addfont('D:\my_fonts\HAKUYOCaoShu3500.ttf') #并不是所有的字体都能正常使用

FontProperties 类

class matplotlib.font_manager.FontProperties(family=None, style=None, variant=None, weight=None, stretch=None, size=None, fname=None)

FontProperties 类的用法与FontEntry相似。定义一个 FontProperties实例,可以设置 text 对象的全部属性,并可以重复使用。无需在创建 text 时一个一个的设置。

Properties Notes
fontfamily or family {FONTNAME, ‘serif’, ‘sans-serif’, ‘cursive’, ‘fantasy’, ‘monospace’}
fontproperties or font or font_properties font_manager.FontProperties or str or pathlib.Path
fontsize or size float or {‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’}
fontstretch or stretch {a numeric value in range 0-1000, ‘ultra-condensed’, ‘extra-condensed’, ‘condensed’, ‘semi-condensed’, ‘normal’, ‘semi-expanded’, ‘expanded’, ‘extra-expanded’, ‘ultra-expanded’}
fontstyle or style {‘normal’, ‘italic’, ‘oblique’}
fontvariant or variant {‘normal’, ‘small-caps’}
fontweight or weight {a numeric value in range 0-1000, ‘ultralight’, ‘light’, ‘normal’, ‘regular’, ‘book’, ‘medium’, ‘roman’, ‘semibold’, ‘demibold’, ‘demi’, ‘bold’, ‘heavy’, ‘extra bold’, ‘black’}
%matplotlib inline

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.font_manager as fm

x = np.arange(0, 10, 0.2)
y = np.sin(x)

#strech,拉伸,相当于word中的字体加宽
font_S = fm.FontProperties(family='Stencil',size=24, stretch=0)
font_M = fm.FontProperties(family='Mistral',size='xx-large',stretch=1000, weight='bold')

fig = plt.figure(constrained_layout=True)

ax = fig.add_subplot(111)
ax.set_title('Axes\'s Title', fontproperties = font_S)
ax.set_xlabel('xaxis label', fontproperties=font_M)

ax.plot(x,y)

plt.show()

一文彻底解决 matplotlib 中的字体管理

matplotlib 可用字体

下面的代码输出了 matplotlib 可用字体,约443种字体。

我的环境中,matplotlib 可用字体数:

#可用的ttf字体

import matplotlib

mf_name = sorted([f.fname for f in matplotlib.font_manager.fontManager.ttflist])

print("matplotlib 可用的ttf字体数:", len(mf_name))

for i in mf_name[0:10]:
    print(i)
matplotlib 可用的ttf字体数: 520
C:\Anaconda3\envs\py38env\lib\site-packages\matplotlib\mpl-data\fonts\ttf\DejaVuSans-Bold.ttf
C:\Anaconda3\envs\py38env\lib\site-packages\matplotlib\mpl-data\fonts\ttf\DejaVuSans-BoldOblique.ttf
C:\Anaconda3\envs\py38env\lib\site-packages\matplotlib\mpl-data\fonts\ttf\DejaVuSans-Oblique.ttf
C:\Anaconda3\envs\py38env\lib\site-packages\matplotlib\mpl-data\fonts\ttf\DejaVuSans.ttf
C:\Anaconda3\envs\py38env\lib\site-packages\matplotlib\mpl-data\fonts\ttf\DejaVuSansDisplay.ttf
C:\Anaconda3\envs\py38env\lib\site-packages\matplotlib\mpl-data\fonts\ttf\DejaVuSansMono-Bold.ttf
C:\Anaconda3\envs\py38env\lib\site-packages\matplotlib\mpl-data\fonts\ttf\DejaVuSansMono-BoldOblique.ttf
C:\Anaconda3\envs\py38env\lib\site-packages\matplotlib\mpl-data\fonts\ttf\DejaVuSansMono-Oblique.ttf
C:\Anaconda3\envs\py38env\lib\site-packages\matplotlib\mpl-data\fonts\ttf\DejaVuSansMono.ttf
C:\Anaconda3\envs\py38env\lib\site-packages\matplotlib\mpl-data\fonts\ttf\DejaVuSerif-Bold.ttf
#可用的 afm 字体

import matplotlib

mf_name = sorted([f.fname for f in matplotlib.font_manager.fontManager.afmlist])

print("matplotlib 可用的 afm 字体数:", len(mf_name))

for i in mf_name[0:10]:
    print(i)
matplotlib 可用的 afm 字体数: 60
C:\Anaconda3\envs\py38env\lib\site-packages\matplotlib\mpl-data\fonts\afm\cmex10.afm
C:\Anaconda3\envs\py38env\lib\site-packages\matplotlib\mpl-data\fonts\afm\cmmi10.afm
C:\Anaconda3\envs\py38env\lib\site-packages\matplotlib\mpl-data\fonts\afm\cmr10.afm
C:\Anaconda3\envs\py38env\lib\site-packages\matplotlib\mpl-data\fonts\afm\cmsy10.afm
C:\Anaconda3\envs\py38env\lib\site-packages\matplotlib\mpl-data\fonts\afm\cmtt10.afm
C:\Anaconda3\envs\py38env\lib\site-packages\matplotlib\mpl-data\fonts\afm\pagd8a.afm
C:\Anaconda3\envs\py38env\lib\site-packages\matplotlib\mpl-data\fonts\afm\pagdo8a.afm
C:\Anaconda3\envs\py38env\lib\site-packages\matplotlib\mpl-data\fonts\afm\pagk8a.afm
C:\Anaconda3\envs\py38env\lib\site-packages\matplotlib\mpl-data\fonts\afm\pagko8a.afm
C:\Anaconda3\envs\py38env\lib\site-packages\matplotlib\mpl-data\fonts\afm\pbkd8a.afm
# 查询可用的系统字体

import matplotlib
import matplotlib.font_manager

mf_fn = sorted(matplotlib.font_manager.findSystemFonts(fontpaths='C:\\Windows\\Fonts', fontext='ttf'))

print("可用的系统字体:", len(mf_fn))
for i in mf_fn[0:10]:
    print(i)
可用的系统字体: 473
C:\Windows\Fonts\AGENCYB.TTF
C:\Windows\Fonts\AGENCYR.TTF
C:\Windows\Fonts\ALGER.TTF
C:\Windows\Fonts\ANTQUAB.TTF
C:\Windows\Fonts\ANTQUABI.TTF
C:\Windows\Fonts\ANTQUAI.TTF
C:\Windows\Fonts\ARIALN.TTF
C:\Windows\Fonts\ARIALNB.TTF
C:\Windows\Fonts\ARIALNBI.TTF
C:\Windows\Fonts\ARIALNI.TTF

列出可用字体名称并显示示例字体

import matplotlib.font_manager
from IPython.core.display import HTML

def make_html(fontname):
    return "<p>{font}: <span style='font-family:{font}; font-size: 24px;'>{font}</p>".format(font=fontname)

af = sorted(set([f.name for f in matplotlib.font_manager.fontManager.ttflist]))

code = "\n".join([make_html(font) for font in af[0:10]])

HTML("<div style='column-count: 2;'>{}</div>".format(code))

一文彻底解决 matplotlib 中的字体管理

matplotlib 常用中文字体名称对照表

Windows的字体对应名称,根据需要自行更换!

黑体 SimHei
微软雅黑 Microsoft YaHei
微软正黑体 Microsoft JhengHei
新宋体 NSimSun
新细明体 PMingLiU
细明体 MingLiU
标楷体 DFKai-SB
仿宋 FangSong
楷体 KaiTi
仿宋_GB2312 FangSong_GB2312
楷体_GB2312 KaiTi_GB2312

宋体:SimSuncss中中文字体(font-family)的英文名称

Windows的一些:
新細明體 PMingLiU 楷体 KaiTi
細明體 MingLiU 仿宋_GB2312 FangSong_GB2312
標楷體 DFKai-SB 楷体_GB2312 KaiTi_GB2312
黑体 SimHei 微軟正黑體 Microsoft JhengHei
新宋体 NSimSun 微软雅黑体 Microsoft YaHei
仿宋 FangSong
装Office会生出来的一些:
隶书 LiSu 方正舒体 FZShuTi
幼圆 YouYuan 方正姚体 FZYaoti
华文细黑 STXihei 华文彩云 STCaiyun
华文楷体 STKaiti 华文琥珀 STHupo
华文宋体 STSong 华文隶书 STLiti
华文中宋 STZhongsong 华文行楷 STXingkai
华文仿宋 STFangsong 华文新魏 STXinwei

matplotlib 中文乱码问题的解决

在matplotlib中,在使用中文的时候经常会出现一些乱码的问题,如中文会变成小方格子。有以下几种解决方案:

方法一:修改配置文件matplotlibrc

不推荐这样做。

#使用下面的命令查看配置文件位置

import matplotlib
matplotlib.matplotlib_fname()
'C:\\Anaconda3\\envs\\py38env\\lib\\site-packages\\matplotlib\\mpl-data\\matplotlibrc'
  1. 一般在C:\Windows\Fonts 里可以找到Mircosoft YaHei UI字体文件
  2. 将字体文件拷贝至下面的目录中

\matplotlib\mpl-data\fonts\ttf

  1. 用写字板或记事本打开matplotlibrc文件:
  • 删除 font.family 前面的 # 并将冒号后面改为“Microsoft YaHei”;
  • 删除 font.sans-serif 前面的 # 并在冒号后面添加“Microsoft YaHei”

194 font.family         : Microsoft YaHei
195 #font.style          : normal
196 #font.variant        : normal
197 #font.weight         : normal
198 #font.stretch        : normal

206 font.sans-serif     : Microsoft YaHei, DejaVu Sans, Bitstream Vera Sans, Computer Modern Sans Serif, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif
207 #font.cursive        : Apple Chancery, Textile, Zapf Chancery, Sand, Script MT, Felipa, cursive
208 #font.fantasy        : Comic Sans MS, Chicago, Charcoal, ImpactWestern, Humor Sans, xkcd, fantasy
209 #font.monospace      : DejaVu Sans Mono, Bitstream Vera Sans Mono, Computer Modern Typewriter, Andale Mono, Nimbus Mono L, Courier New, Courier, Fixed, Terminal, monospace

修改后保存,重新运行程序。

方法二:动态设置参数(可用)

在python脚本中动态设置matplotlibrc,这样就避免了更改配置文件的麻烦,方便灵活,例如:

import matplotlib as mpl

mpl.rcParams[‘font.sans-serif] = [‘SimHei’]

由于更改了字体导致显示不出负号,将配署文件中axes.unicode minus : True修改为False 就可以了,当然这而可以在代码中完成。

import matplotlib as mpl

mpl.rcParams['font.sans-serif'] = ['FangSong'] # 指定默认字体

mpl.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号’-'显示为方块的问题

临时方法

优点:直接在代码中指定中文字体文件,在每个出现中文的地方指定 fontproperties为刚才设置的字体;

缺点:每个出现中文的地方如title都要指定字体,并不是每个地方如legend都提供指定字体的参数。

适用场合:偶尔使用中文显示,出现中文的地方较少。

myfont = matplotlib.font_manager.FontProperties(fname=r"c:\windows\fonts\simsun.ttc", size=14)

直接设置为中文时

ax.set_title(u'中文', fontproperties = myfont)

还可以直接:

ax.set_title(u'中文', fontproperties='SimHei')

方法三:使用字体管理器(推荐的方法)

python有个字体管理器,font_manager, 使用它来管理和设置字体。

示例见前面。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XTtjSbff-1605853704546)(output_104_0.png)]



附录

字体族

serif 衬线字体族

示例:

  • Times New Roman、MS Georgia
  • 宋体、仿宋

sans-serif 无衬线字体族

示例:

  • MS Trebuchet、MS Arial、MS Verdana
  • 黑体、幼圆、隶书、楷体

cursive 手写字体族

示例:

  • Caflisch Script、Adobe Poetica
  • 迷你简黄草、华文行草

monospace 等宽字体族

示例:

  • Courier、MS Courier New、Prestige
  • 大多数中文字体

–End–

本文地址:https://blog.csdn.net/sinat_32570141/article/details/109848383