查找适用于matplotlib的中文字体名称与实际文件名对应关系的方法


Posted in Python onJanuary 05, 2021

问题来源

如何在matplotlib中使用中文字体是老问题了,相关文章非常多。
前几天有人问我如何知道中文字体名称和实际文件的对应关系时,才想起来原来没思考过这个问题,只能让他记住字体与文件的对应关系或者去fonts目录查看。
难道真的就没有稍微自动化、智能化的查看支持matplotlib的字体名称与文件的对应关系的方法?

问题解决步骤

matplotlib与字体相关的模块是font_manager,观察源码font_manager.py可知:

1. matplotlib支持哪种类型的字体?

def get_fontext_synonyms(fontext):
  """
  Return a list of file extensions extensions that are synonyms for
  the given file extension *fileext*.
  """
  return {
    'afm': ['afm'],
    'otf': ['otf', 'ttc', 'ttf'],
    'ttc': ['otf', 'ttc', 'ttf'],
    'ttf': ['otf', 'ttc', 'ttf'],
  }[fontext]

由此可知matplotlib只支持ttfafm字体。

  • ‘ttf': TrueType and OpenType fonts (.ttf, .ttc, .otf)
  • ‘afm': Adobe Font Metrics (.afm)

2. matplotlib如何查找系统字体?

findSystemFonts模块函数的作用是查找系统字体。
def findSystemFonts(fontpaths=None, fontext='ttf'): -->list
参数fontext默认值为'ttf',另外还支持值'afm'
参数fontpaths默认值是None
对于fontpaths有两种种情况。

fontpathsNone

函数会判断操作系统,如果是Windows,调用函数win32InstalledFonts,如果不是Windows,调用函数get_fontconfig_fonts

对于Windows,函数win32InstalledFonts到以下路径查找。

# OS Font paths
MSFolders = \
  r'Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders'
MSFontDirectories = [
  r'SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts',
  r'SOFTWARE\Microsoft\Windows\CurrentVersion\Fonts']
MSUserFontDirectories = [
  str(Path.home() / 'AppData/Local/Microsoft/Windows/Fonts'),
  str(Path.home() / 'AppData/Roaming/Microsoft/Windows/Fonts'),
]

对于非Windows操作系统,函数get_fontconfig_fonts主要依托fontconfig包(即fc-list命令)查找字体,要求fontconfig>=2.7

fontpaths不为None

fontpaths不为None时,通过list_fonts()函数查找字体。
list_fonts()函数其实一个通用的按路径、扩展名递归遍历文件路径的函数。

def list_fonts(directory, extensions):
  """
  Return a list of all fonts matching any of the extensions, found
  recursively under the directory.
  """
  extensions = ["." + ext for ext in extensions]
  return [os.path.join(dirpath, filename)
      # os.walk ignores access errors, unlike Path.glob.
      for dirpath, _, filenames in os.walk(directory)
      for filename in filenames
      if Path(filename).suffix.lower() in extensions]

3.matplotlib如何查找matplotlib自带字体?

安装matplotlib时,会在site-packages\matplotlib\mpl-data\fonts目录放置一系列字体。

通过源码可知fonts目录下有'ttf', 'afm', 'pdfcorefonts'3个子目录。

paths = [cbook._get_data_path('fonts', subdir)
         for subdir in ['ttf', 'afm', 'pdfcorefonts']]
In [1]: import matplotlib.cbook as cbook
In [2]: paths = [cbook._get_data_path('fonts', subdir)  for subdir in ['ttf', 'afm', 'pdfcorefonts']]
In [3]: paths
Out[4]:
[WindowsPath('c:/users/administrator/appdata/local/programs/python/python37/lib/site-packages/matplotlib/mpl-data/fonts/ttf'),
 WindowsPath('c:/users/administrator/appdata/local/programs/python/python37/lib/site-packages/matplotlib/mpl-data/fonts/afm'),
 WindowsPath('c:/users/administrator/appdata/local/programs/python/python37/lib/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts')]

4.matplotlib如何生成字体列表?

FontManager类是matplotlib管理字体的重要类,是一个单例类。FontManager实例在构造后会创建一个ttf字体列表和一个afm字体列表,并会缓存他们的字体属性。
下面简单看看ttflistafmlist列表的元素的属性。

In [1]: import matplotlib.font_manager as mf
In [2]: ttflist=mf.FontManager().ttflist
In [3]: vars(ttflist[0])
Out[3]:
{'fname': 'c:\\users\\administrator\\appdata\\local\\programs\\python\\python37\\lib\\site-packages\\matplotlib\\mpl-data\\fonts\\ttf\\DejaVuSansMono-BoldOblique.ttf',
 'name': 'DejaVu Sans Mono',
 'style': 'oblique',
 'variant': 'normal',
 'weight': 700,
 'stretch': 'normal',
 'size': 'scalable'}
In [4]: len(ttflist)
Out[4]: 252
In [5]: afmlist=mf.FontManager().afmlist
In [6]: vars(afmlist[0])
Out[6]:
{'fname': 'c:\\users\\administrator\\appdata\\local\\programs\\python\\python37\\lib\\site-packages\\matplotlib\\mpl-data\\fonts\\afm\\pagko8a.afm',
 'name': 'ITC Avant Garde Gothic',
 'style': 'italic',
 'variant': 'normal',
 'weight': 'book',
 'stretch': 'normal',
 'size': 'scalable'}
In [7]: len(afmlist)
Out[7]: 60

5.matplotlib的字体属性缓存在哪里?

前面了解到matplotlib会缓存字体属性那在什么位置呢?
根据源码可知,字体缓存的所在目录是.matplotlib,缓存文件是fontlist-v330.json(文件名与版本有关)。在某些老版本的matplotlib中字体缓存文件名是fontList.cache

_fmcache = os.path.join(
  mpl.get_cachedir(), 'fontlist-v{}.json'.format(FontManager.__version__))
In [1]: import matplotlib
In [2]: matplotlib.get_cachedir()
Out[2]: 'C:\\Users\\Administrator\\.matplotlib'

6. 怎么知道哪些字体是中文字体?

虽然在前面已经知道matplotlib会把系统字体和自带字体信息存放在ttflistafmlist中,但是在这些字体信息中也不容易确定哪些是中文字体。
通过资料查找有3种方法:

查看Windows的fonts系统目录中显示的字体名称和文件名属性。这种方法效率太低!

通过注册表项[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts]查看字体名和字体文件名称映射。这种方法一些系统字体仍然看不到汉字名称。

查找适用于matplotlib的中文字体名称与实际文件名对应关系的方法

根据第1种方法想到了去查字体文件的元数据,Python相关的库有两个:fonttools,作者是老爹Guido的弟弟Just van RossumTTFQuery,基于fonttools的TTF包,只能查看TTF文件而且最后更新日期是2012年。

TTFQery项目地址https://pypi.org/project/TTFQuery/
源码中有些小问题,源码不算复杂,直接修改。

import sys
from fontTools.ttLib import TTFont
from fontTools.ttLib.ttCollection import TTCollection

UNICODE_ENCODINGS = {0: 'Unicode 1.0 semantics',
           1: 'Unicode 1.1 semantics',
           2: 'Unicode 1.1 semantics',
           3: 'Unicode 2.0 and onwards semantics, Unicode BMP only (cmap subtable formats 0, 4, 6).',
           4: 'Unicode 2.0 and onwards semantics, Unicode full repertoire (cmap subtable formats 0, 4, 6, 10, 12).',
           5: 'Unicode Variation Sequences (cmap subtable format 14).',
           6: 'Unicode Variation Sequences (cmap subtable format 14).'}


WINDOWS_ENCODINGS = {0: 'Symbol',
           1: 'Unicode BMP(UCS-2)',
           2: 'ShiftJIS',
           3: 'PRC',
           4: 'Big5',
           5: 'Wansung',
           6: 'Johab',
           7: 'Reserved',
           8: 'Reserved',
           9: 'Reserved',
           10: 'Unicode UCS-4'}


WINDOWS_LANGUAGES = {1025: 'Arabic/Saudi Arabia',
           1026: 'Bulgarian/Bulgaria',
           1027: 'Catalan/Catalan',
           1028: 'Chinese/Taiwan',
           1029: 'Czech/Czech Republic',
           1030: 'Danish/Denmark',
           1031: 'German/Germany',
           1032: 'Greek/Greece',
           1033: 'English/United States',
           1034: 'Spanish (Traditional Sort)/Spain',
           1035: 'Finnish/Finland',
           1036: 'French/France',
           1037: 'Hebrew/Israel',
           1038: 'Hungarian/Hungary',
           1039: 'Icelandic/Iceland',
           1040: 'Italian/Italy',
           1041: 'Japanese/Japan',
           1042: 'Korean/Korea',
           1043: 'Dutch/Netherlands',
           1044: 'Norwegian (Bokmal)/Norway',
           1045: 'Polish/Poland',
           1046: 'Portuguese/Brazil',
           1047: 'Romansh/Switzerland',
           1048: 'Romanian/Romania',
           1049: 'Russian/Russia',
           1050: 'Croatian/Croatia',
           1051: 'Slovak/Slovakia',
           1052: 'Albanian/Albania',
           1053: 'Swedish/Sweden',
           1054: 'Thai/Thailand',
           1055: 'Turkish/Turkey',
           1056: 'Urdu/Islamic Republic of Pakistan',
           1057: 'Indonesian/Indonesia',
           1058: 'Ukrainian/Ukraine',
           1059: 'Belarusian/Belarus',
           1060: 'Slovenian/Slovenia',
           1061: 'Estonian/Estonia',
           1062: 'Latvian/Latvia',
           1063: 'Lithuanian/Lithuania',
           1064: 'Tajik (Cyrillic)/Tajikistan',
           1066: 'Vietnamese/Vietnam',
           1067: 'Armenian/Armenia',
           1068: 'Azeri (Latin)/Azerbaijan',
           1069: 'Basque/Basque',
           1070: 'Upper Sorbian/Germany',
           1071: 'Macedonian (FYROM)/Former Yugoslav Republic of Macedonia',
           1074: 'Setswana/South Africa',
           1076: 'isiXhosa/South Africa',
           1077: 'isiZulu/South Africa',
           1078: 'Afrikaans/South Africa',
           1079: 'Georgian/Georgia',
           1080: 'Faroese/Faroe Islands',
           1081: 'Hindi/India',
           1082: 'Maltese/Malta',
           1083: 'Sami (Northern)/Norway',
           1086: 'Malay/Malaysia',
           1087: 'Kazakh/Kazakhstan',
           1088: 'Kyrgyz/Kyrgyzstan',
           1089: 'Kiswahili/Kenya',
           1090: 'Turkmen/Turkmenistan',
           1091: 'Uzbek (Latin)/Uzbekistan',
           1092: 'Tatar/Russia',
           1093: 'Bengali/India',
           1094: 'Punjabi/India',
           1095: 'Gujarati/India',
           1096: 'Odia (formerly Oriya)/India',
           1097: 'Tamil/India',
           1098: 'Telugu/India',
           1099: 'Kannada/India',
           1100: 'Malayalam/India',
           1101: 'Assamese/India',
           1102: 'Marathi/India',
           1103: 'Sanskrit/India',
           1104: 'Mongolian (Cyrillic)/Mongolia',
           1105: 'Tibetan/PRC',
           1106: 'Welsh/United Kingdom',
           1107: 'Khmer/Cambodia',
           1108: 'Lao/Lao P.D.R.',
           1110: 'Galician/Galician',
           1111: 'Konkani/India',
           1114: 'Syriac/Syria',
           1115: 'Sinhala/Sri Lanka',
           1117: 'Inuktitut/Canada',
           1118: 'Amharic/Ethiopia',
           1121: 'Nepali/Nepal',
           1122: 'Frisian/Netherlands',
           1123: 'Pashto/Afghanistan',
           1124: 'Filipino/Philippines',
           1125: 'Divehi/Maldives',
           1128: 'Hausa (Latin)/Nigeria',
           1130: 'Yoruba/Nigeria',
           1131: 'Quechua/Bolivia',
           1132: 'Sesotho sa Leboa/South Africa',
           1133: 'Bashkir/Russia',
           1134: 'Luxembourgish/Luxembourg',
           1135: 'Greenlandic/Greenland',
           1136: 'Igbo/Nigeria',
           1144: 'Yi/PRC',
           1146: 'Mapudungun/Chile',
           1148: 'Mohawk/Mohawk',
           1150: 'Breton/France',
           1152: 'Uighur/PRC',
           1153: 'Maori/New Zealand',
           1154: 'Occitan/France',
           1155: 'Corsican/France',
           1156: 'Alsatian/France',
           1157: 'Yakut/Russia',
           1158: "K'iche/Guatemala",
           1159: 'Kinyarwanda/Rwanda',
           1160: 'Wolof/Senegal',
           1164: 'Dari/Afghanistan',
           2049: 'Arabic/Iraq',
           2052: "Chinese/People's Republic of China",
           2055: 'German/Switzerland',
           2057: 'English/United Kingdom',
           2058: 'Spanish/Mexico',
           2060: 'French/Belgium',
           2064: 'Italian/Switzerland',
           2067: 'Dutch/Belgium',
           2068: 'Norwegian (Nynorsk)/Norway',
           2070: 'Portuguese/Portugal',
           2074: 'Serbian (Latin)/Serbia',
           2077: 'Sweden/Finland',
           2092: 'Azeri (Cyrillic)/Azerbaijan',
           2094: 'Lower Sorbian/Germany',
           2107: 'Sami (Northern)/Sweden',
           2108: 'Irish/Ireland',
           2110: 'Malay/Brunei Darussalam',
           2115: 'Uzbek (Cyrillic)/Uzbekistan',
           2117: 'Bengali/Bangladesh',
           2128: "Mongolian (Traditional)/People's Republic of China",
           2141: 'Inuktitut (Latin)/Canada',
           2143: 'Tamazight (Latin)/Algeria',
           2155: 'Quechua/Ecuador',
           3073: 'Arabic/Egypt',
           3076: 'Chinese/Hong Kong S.A.R.',
           3079: 'German/Austria',
           3081: 'English/Australia',
           3082: 'Spanish (Modern Sort)/Spain',
           3084: 'French/Canada',
           3098: 'Serbian (Cyrillic)/Serbia',
           3131: 'Sami (Northern)/Finland',
           3179: 'Quechua/Peru',
           4097: 'Arabic/Libya',
           4100: 'Chinese/Singapore',
           4103: 'German/Luxembourg',
           4105: 'English/Canada',
           4106: 'Spanish/Guatemala',
           4108: 'French/Switzerland',
           4122: 'Croatian (Latin)/Bosnia and Herzegovina',
           4155: 'Sami (Lule)/Norway',
           5121: 'Arabic/Algeria',
           5124: 'Chinese/Macao S.A.R.',
           5127: 'German/Liechtenstein',
           5129: 'English/New Zealand',
           5130: 'Spanish/Costa Rica',
           5132: 'French/Luxembourg',
           5146: 'Bosnian (Latin)/Bosnia and Herzegovina',
           5179: 'Sami (Lule)/Sweden',
           6145: 'Arabic/Morocco',
           6153: 'English/Ireland',
           6154: 'Spanish/Panama',
           6156: 'French/Principality of Monaco',
           6170: 'Serbian (Latin)/Bosnia and Herzegovina',
           6203: 'Sami (Southern)/Norway',
           7169: 'Arabic/Tunisia',
           7177: 'English/South Africa',
           7178: 'Spanish/Dominican Republic',
           7194: 'Serbian (Cyrillic)/Bosnia and Herzegovina',
           7227: 'Sami (Southern)/Sweden',
           8193: 'Arabic/Oman',
           8201: 'English/Jamaica',
           8202: 'Spanish/Venezuela',
           8218: 'Bosnian (Cyrillic)/Bosnia and Herzegovina',
           8251: 'Sami (Skolt)/Finland',
           9217: 'Arabic/Yemen',
           9225: 'English/Caribbean',
           9226: 'Spanish/Colombia',
           9275: 'Sami (Inari)/Finland',
           10241: 'Arabic/Syria',
           10249: 'English/Belize',
           10250: 'Spanish/Peru',
           11265: 'Arabic/Jordan',
           11273: 'English/Trinidad and Tobago',
           11274: 'Spanish/Argentina',
           12289: 'Arabic/Lebanon',
           12297: 'English/Zimbabwe',
           12298: 'Spanish/Ecuador',
           13313: 'Arabic/Kuwait',
           13321: 'English/Republic of the Philippines',
           13322: 'Spanish/Chile',
           14337: 'Arabic/U.A.E.',
           14346: 'Spanish/Uruguay',
           15361: 'Arabic/Bahrain',
           15370: 'Spanish/Paraguay',
           16385: 'Arabic/Qatar',
           16393: 'English/India',
           16394: 'Spanish/Bolivia',
           17417: 'English/Malaysia',
           17418: 'Spanish/El Salvador',
           18441: 'English/Singapore',
           18442: 'Spanish/Honduras',
           19466: 'Spanish/Nicaragua',
           20490: 'Spanish/Puerto Rico',
           21514: 'Spanish/United States'}

MACINTOSH_ENCODINGS = {0: 'Roman',
            1: 'Japanese',
            2: 'Chinese',
            3: 'Korean',
            4: 'Arabic',
            5: 'Hebrew',
            6: 'Greek',
            7: 'Russian',
            8: 'RSymbol',
            9: 'Devanagari',
            10: 'Gurmukhi',
            11: 'Gujarati',
            12: 'Oriya',
            13: 'Bengali',
            14: 'Tamil',
            15: 'Telugu',
            16: 'Kannada',
            17: 'Malayalam',
            18: 'Sinhalese',
            19: 'Burmese',
            20: 'Khmer',
            21: 'Thai',
            22: 'Laotian',
            23: 'Georgian',
            24: 'Armenian',
            25: 'Chinese',
            26: 'Tibetan',
            27: 'Mongolian',
            28: 'Geez',
            29: 'Slavic',
            30: 'Vietnamese',
            31: 'Sindhi',
            32: 'Uninterpreted'}

MACINTOSH_LANGUAGES = {0: 'English',
            1: 'French',
            2: 'German',
            3: 'Italian',
            4: 'Dutch',
            5: 'Swedish',
            6: 'Spanish',
            7: 'Danish',
            8: 'Portuguese',
            9: 'Norwegian',
            10: 'Hebrew',
            11: 'Japanese',
            12: 'Arabic',
            13: 'Finnish',
            14: 'Inuktitut',
            15: 'Icelandic',
            16: 'Maltese',
            17: 'Turkish',
            18: 'Croatian',
            19: 'Chinese (Traditional)',
            20: 'Urdu',
            21: 'Hindi',
            22: 'Thai',
            23: 'Korean',
            24: 'Lithuanian',
            25: 'Polish',
            26: 'Hungarian',
            27: 'Estonian',
            28: 'Latvian',
            29: 'Sami',
            30: 'Faroese',
            31: 'Farsi/Persian',
            32: 'Russian',
            33: 'Chinese (Simplified)',
            34: 'Flemish',
            35: 'Irish Gaelic',
            36: 'Albanian',
            37: 'Romanian',
            38: 'Czech',
            39: 'Slovak',
            40: 'Slovenian',
            41: 'Yiddish',
            42: 'Serbian',
            43: 'Macedonian',
            44: 'Bulgarian',
            45: 'Ukrainian',
            46: 'Byelorussian',
            47: 'Uzbek',
            48: 'Kazakh',
            49: 'Azerbaijani (Cyrillic script)',
            50: 'Azerbaijani (Arabic script)',
            51: 'Armenian',
            52: 'Georgian',
            53: 'Moldavian',
            54: 'Kirghiz',
            55: 'Tajiki',
            56: 'Turkmen',
            57: 'Mongolian (Mongolian script)',
            58: 'Mongolian (Cyrillic script)',
            59: 'Pashto',
            60: 'Kurdish',
            61: 'Kashmiri',
            62: 'Sindhi',
            63: 'Tibetan',
            64: 'Nepali',
            65: 'Sanskrit',
            66: 'Marathi',
            67: 'Bengali',
            68: 'Assamese',
            69: 'Gujarati',
            70: 'Punjabi',
            71: 'Oriya',
            72: 'Malayalam',
            73: 'Kannada',
            74: 'Tamil',
            75: 'Telugu',
            76: 'Sinhalese',
            77: 'Burmese',
            78: 'Khmer',
            79: 'Lao',
            80: 'Vietnamese',
            81: 'Indonesian',
            82: 'Tagalong',
            83: 'Malay (Roman script)',
            84: 'Malay (Arabic script)',
            85: 'Amharic',
            86: 'Tigrinya',
            87: 'Galla',
            88: 'Somali',
            89: 'Swahili',
            90: 'Kinyarwanda/Ruanda',
            91: 'Rundi',
            92: 'Nyanja/Chewa',
            93: 'Malagasy',
            94: 'Esperanto',
            128: 'Welsh',
            129: 'Basque',
            130: 'Catalan',
            131: 'Latin',
            132: 'Quenchua',
            133: 'Guarani',
            134: 'Aymara',
            135: 'Tatar',
            136: 'Uighur',
            137: 'Dzongkha',
            138: 'Javanese (Roman script)',
            139: 'Sundanese (Roman script)',
            140: 'Galician',
            141: 'Afrikaans',
            142: 'Breton',
            144: 'Scottish Gaelic',
            145: 'Manx Gaelic',
            146: 'Irish Gaelic (with dot above)',
            147: 'Tongan',
            148: 'Greek (polytonic)',
            149: 'Greenlandic',
            150: 'Azerbaijani (Roman script)'}

ISO_IDS = {
  0: '7-bit ASCII',
  1: 'ISO 10646',
  2: 'ISO 8859-1'
}

CUSTOMS = {}


PLATFORMS = {0: {'name': 'Unicode',
         'encodings': UNICODE_ENCODINGS,
         'languages': UNICODE_ENCODINGS},
       1: {'name': 'Macintosh',
         'encodings': MACINTOSH_ENCODINGS,
         'languages': MACINTOSH_LANGUAGES},
       2: {'name': 'ISO [deprecated]',
         'encodings': ISO_IDS,
         'languages': ISO_IDS},
       3: {'name': 'Windows',
         'encodings': WINDOWS_ENCODINGS,
         'languages': WINDOWS_LANGUAGES},
       4: {'name': 'Custom',
         'encodings': CUSTOMS,
         'languages': CUSTOMS}}


NAME_TABLE = {0: 'Copyright Notice',
       1: 'Font Family',
       2: 'SubFamily',
       3: 'Unique Font Identifier',
       4: 'Full Font Name',
       5: 'Version',
       6: 'PostScript Name',
       7: 'Trademark',
       8: 'Manufacturer Name',
       9: 'Designer',
       10: 'Description',
       11: 'Vendor URL',
       12: 'Designer URL',
       13: 'License Description',
       14: 'License Info URL',
       15: 'Reserved',
       16: 'Typographic Family',
       17: 'Typographic SubFamily',
       18: 'Compatible Full',
       19: 'Sample Text',
       20: 'PostScript CID findfont name',
       21: 'WWS Family Name',
       22: 'WWS SubFamily Name',
       23: 'Light Background Pallete',
       24: 'Dark Background Pallete',
       25: 'Variations PostScript Name Prefix'}


ENCODINGS = {
  "Roman": 'latin_1'
}

def parse_meta(font):
  """The main meta parsing function. Thanks to Fonttools library."""
  data = {}
  for nti in font['name'].names:
    key = nti.nameID
    platform_data = PLATFORMS[nti.platformID]
    if platform_data['name'] == 'Custom':
      encoding = {'id': 0, 'value': 'Custom'}
      language = {'id': 0, 'value': 'Custom'}
    else:
      encoding = {'id': nti.platEncID,
            'value': platform_data['encodings'].get(nti.platEncID, "Unknown")}
      language = {'id': nti.langID,
            'value': platform_data['languages'].get(nti.langID, "Unknown")}
    name_str = nti.toStr()
    field = NAME_TABLE.get(nti.nameID, False)
    if not field:
      if 26 <= nti.nameID <= 255:
        field = 'Reserved [{}]'.format(nti.nameID)
      elif 256 <= nti.nameID:
        field = 'Font Specific[{}]'.format(nti.nameID)

    data[key] = {"field": field,
          "value": name_str,
          "encoding": encoding,
          "language": language
    }
  return data

def get_font_name(data, language=None):
  language_name = data.get(4).get('language').get('value')
  font_full_name = data.get(4).get('value')

  if language is None:
    return font_full_name
  else:
    if language in language_name:
      return font_full_name
    

if __name__ == '__main__':
  from pathlib import Path
  import matplotlib.font_manager as fm
  
  ttflist=fm.FontManager().ttflist
  
  for f in ttflist:
    if Path(f.fname).suffix.lower()=='.ttf':
      # 输出字体元数据中语言包含有中文的TTF字体
      data = parse_meta(TTFont(f.fname))
      out_ttf = get_font_name(data,'Chinese')
      if out_ttf:
        print(f.fname,f.name,out_ttf)
    elif Path(f.fname).suffix.lower()=='.ttc':
      # 输出所有TTC字体中包含的字体名称信息
      ttc = TTCollection(f.fname)
      for ttf in ttc:
        ttc_data = parse_meta(ttf)
        out_ttc = get_font_name(ttc_data,'Chinese')
        if out_ttc:
          print(f.fname,f.name,out_ttc)

ttc文件很特殊,它是多个ttf文件集合,常用字体宋体微软雅黑等在Windows10中都是ttc文件,而且奇怪的是很多语言信息不是中文的ttc字体也可以显示中文。

C:\Windows\Fonts\STHUPO.TTF STHupo 华文琥珀
C:\Windows\Fonts\mingliub.ttc MingLiU-ExtB ?明?-ExtB
C:\Windows\Fonts\mingliub.ttc MingLiU-ExtB 新?明?-ExtB
C:\Windows\Fonts\mingliub.ttc MingLiU-ExtB ?明?_HKSCS-ExtB
C:\Windows\Fonts\simkai.ttf KaiTi 楷体
C:\Windows\Fonts\STXIHEI.TTF STXihei 华文细黑
C:\Users\Administrator\AppData\Local\Microsoft\Windows\Fonts\仿宋_GB2312.ttf FangSong_GB2312 仿宋_GB2312
C:\Users\Administrator\AppData\Local\Microsoft\Windows\Fonts\楷体_GB2312.ttf KaiTi_GB2312 楷体_GB2312
C:\Windows\Fonts\STXINGKA.TTF STXingkai 华文行楷
C:\Windows\Fonts\STCAIYUN.TTF STCaiyun 华文彩云
C:\Windows\Fonts\simsun.ttc SimSun 宋体
C:\Windows\Fonts\simsun.ttc SimSun 新宋体
C:\Windows\Fonts\STKAITI.TTF STKaiti 华文楷体
C:\Windows\Fonts\msjhl.ttc Microsoft JhengHei 微?正黑? Light
C:\Windows\Fonts\msjhl.ttc Microsoft JhengHei Microsoft JhengHei UI Light
C:\Users\Administrator\AppData\Local\Microsoft\Windows\Fonts\华文中宋.ttf STZhongsong 华文中宋
C:\Windows\Fonts\FZYTK.TTF FZYaoTi 方正姚体
C:\Users\Administrator\AppData\Local\Microsoft\Windows\Fonts\方正卡通简体.ttf FZKaTong-M19S 方正卡通简体
C:\Windows\Fonts\simhei.ttf SimHei 黑体
C:\Windows\Fonts\方正粗黑宋简体.ttf FZCuHeiSongS-B-GB 方正粗黑宋简体
C:\Windows\Fonts\Deng.ttf DengXian 等线
C:\Users\Administrator\AppData\Local\Microsoft\Windows\Fonts\FZXBSJW.TTF FZXiaoBiaoSong-B05S 方正小标宋简体
C:\Windows\Fonts\Dengl.ttf DengXian 等线 Light
C:\Windows\Fonts\msjh.ttc Microsoft JhengHei 微?正黑?
C:\Windows\Fonts\msjh.ttc Microsoft JhengHei Microsoft JhengHei UI
C:\Windows\Fonts\msyh.ttc Microsoft YaHei 微软雅黑
C:\Windows\Fonts\msyh.ttc Microsoft YaHei Microsoft Yahei UI
C:\Windows\Fonts\STFANGSO.TTF STFangsong 华文仿宋
C:\Windows\Fonts\simfang.ttf FangSong 仿宋
C:\Windows\Fonts\SIMLI.TTF LiSu 隶书
C:\Windows\Fonts\SIMYOU.TTF YouYuan 幼圆
C:\Windows\Fonts\STLITI.TTF STLiti 华文隶书
C:\Windows\Fonts\Dengb.ttf DengXian 等线 Bold
C:\Windows\Fonts\msyhl.ttc Microsoft YaHei 微软雅黑 Light
C:\Windows\Fonts\msyhl.ttc Microsoft YaHei Microsoft YaHei UI Light
C:\Windows\Fonts\STSONG.TTF STSong 华文宋体
C:\Windows\Fonts\STXINWEI.TTF STXinwei 华文新魏
C:\Windows\Fonts\FZSTK.TTF FZShuTi 方正舒体

参考

https://matplotlib.org/api/font_manager_api.html
http://ttfquery.sourceforge.net/
https://fonttools.readthedocs.io/en/latest/ttLib/index.html

到此这篇关于查找适用于matplotlib的中文字体名称与实际文件名对应关系的方法的文章就介绍到这了,更多相关matplotlib中文字体名称与实际文件名对应内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
使用python调用浏览器并打开一个网址的例子
Jun 05 Python
跟老齐学Python之折腾一下目录
Oct 24 Python
python实现的DES加密算法和3DES加密算法实例
Jun 03 Python
Python简单网络编程示例【客户端与服务端】
May 26 Python
python构建深度神经网络(续)
Mar 10 Python
python爬虫爬取幽默笑话网站
Oct 24 Python
对django 2.x版本中models.ForeignKey()外键说明介绍
Mar 30 Python
Django {{ MEDIA_URL }}无法显示图片的解决方式
Apr 07 Python
Django admin组件的使用
Oct 24 Python
如何在pycharm中安装第三方包
Oct 27 Python
python爬虫scrapy图书分类实例讲解
Nov 23 Python
python 基于opencv去除图片阴影
Jan 26 Python
微软开源最强Python自动化神器Playwright(不用写一行代码)
Jan 05 #Python
Python读取ini配置文件传参的简单示例
Jan 05 #Python
matplotlib实现数据实时刷新的示例代码
Jan 05 #Python
Matplotlib配色之Colormap详解
Jan 05 #Python
matplotlib 使用 plt.savefig() 输出图片去除旁边的空白区域
Jan 05 #Python
python实现文件+参数发送request的实例代码
Jan 05 #Python
为2021年的第一场雪锦上添花:用matplotlib绘制雪花和雪景
Jan 05 #Python
You might like
discuz 首页四格:最新话题+最新回复+热门话题+精华文章插件
2007/08/19 PHP
php socket方式提交的post详解
2008/07/19 PHP
php 冒泡排序 交换排序法
2011/05/10 PHP
php分页代码学习示例分享
2014/02/20 PHP
PHP实现阳历到农历转换的类实例
2015/03/07 PHP
thinkPHP自动验证、自动添加及表单错误问题分析
2016/10/17 PHP
extjs 列表框(multiselect)的动态添加列表项的方法
2009/07/31 Javascript
用Javascript 和 CSS 实现脚注(Footnote)效果
2009/09/09 Javascript
js中更短的 Array 类型转换
2011/10/30 Javascript
Javascript 判断是否存在函数的方法
2013/01/03 Javascript
JavaScript SHA512加密算法详细代码
2016/10/06 Javascript
JavaScript常见的五种数组去重的方式
2016/12/15 Javascript
jQuery为某个div加入行样式
2017/06/09 jQuery
iview table高度动态设置方法
2018/03/14 Javascript
JavaScript反射与依赖注入实例详解
2018/05/29 Javascript
解决vuejs 使用value in list 循环遍历数组出现警告的问题
2018/09/26 Javascript
微信小程序picker组件关于objectArray数据类型的绑定方法
2019/03/13 Javascript
Vue使用Proxy监听所有接口状态的方法实现
2019/06/07 Javascript
javascript实现简易聊天室
2019/07/12 Javascript
[01:03:22]LGD vs OG 2018国际邀请赛淘汰赛BO3 第一场 8.25
2018/08/29 DOTA
跟老齐学Python之从if开始语句的征程
2014/09/14 Python
python中的装饰器详解
2015/04/13 Python
Python编程使用tkinter模块实现计算器软件完整代码示例
2017/11/29 Python
PyQt5实现简单数据标注工具
2019/03/18 Python
Python中面向对象你应该知道的一下知识
2019/07/10 Python
python用win32gui遍历窗口并设置窗口位置的方法
2019/07/26 Python
win10系统下python3安装及pip换源和使用教程
2020/01/06 Python
python实现飞船大战
2020/04/24 Python
python定时截屏实现
2020/11/02 Python
加拿大最大的箱包及旅游配件零售商:Bentley Leathers
2017/07/19 全球购物
铭立家具面试题
2012/12/06 面试题
员工培训心得体会
2013/12/30 职场文书
最美乡村医生事迹材料
2014/06/02 职场文书
Python关于OS文件目录处理的实例分享
2021/05/23 Python
安装配置mysql及Navicat prenium的详细流程
2021/06/10 MySQL
Python实现PIL图像处理库绘制国际象棋棋盘
2021/07/16 Python