查找适用于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正则表达式使用范例分享
Dec 04 Python
python 根据pid杀死相应进程的方法
Jan 16 Python
Python正则简单实例分析
Mar 21 Python
对python中的高效迭代器函数详解
Oct 18 Python
在pycharm中设置显示行数的方法
Jan 16 Python
浅析Python 读取图像文件的性能对比
Mar 07 Python
Python正则表达式匹配和提取IP地址
Jun 06 Python
python3中rank函数的用法
Nov 27 Python
在tensorflow中实现屏蔽输出的log信息
Feb 04 Python
python应用Axes3D绘图(批量梯度下降算法)
Mar 25 Python
pyautogui自动化控制鼠标和键盘操作的步骤
Apr 01 Python
Python+tkinter实现高清图片保存
Mar 13 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
php 魔术方法使用说明
2009/10/20 PHP
如何在标题栏显示框架内页面的标题
2007/02/03 Javascript
JavaScript DOM 学习第七章 表单的扩展
2010/02/19 Javascript
关于Mozilla浏览器不支持innerText的解决办法
2011/01/01 Javascript
jquery 滚动条事件简单实例
2013/07/12 Javascript
浅析JavaScript原型继承的陷阱
2013/12/03 Javascript
使用iframe window的scroll方法控制iframe页面滚动
2014/03/05 Javascript
jquery仿百度经验滑动切换浏览效果
2015/04/14 Javascript
基于JavaScript实现动态创建表格和增加表格行数
2015/12/20 Javascript
深入理解Node.js中的进程管理
2017/03/13 Javascript
JavaScript实现移动端轮播效果
2017/06/06 Javascript
React中使用collections时key的重要性详解
2017/08/07 Javascript
React组件重构之嵌套+继承及高阶组件详解
2018/07/19 Javascript
java实现单链表增删改查的实例代码详解
2019/08/30 Javascript
vue项目中在可编辑div光标位置插入内容的实现代码
2020/01/07 Javascript
快速解决Vue、element-ui的resetFields()方法重置表单无效的问题
2020/08/12 Javascript
使用Protocol Buffers的C语言拓展提速Python程序的示例
2015/04/16 Python
python连接字符串的方法小结
2015/07/13 Python
详解Python3中字符串中的数字提取方法
2017/01/14 Python
python基础教程项目二之画幅好画
2018/04/02 Python
Windows 64位下python3安装nltk模块
2018/09/19 Python
详解Python连接MySQL数据库的多种方式
2019/04/16 Python
python 实现将多条曲线画在一幅图上的方法
2019/07/07 Python
django用户登录验证的完整示例代码
2019/07/21 Python
python字符串分割及字符串的一些常规方法
2019/07/24 Python
在win64上使用bypy进行百度网盘文件上传功能
2020/01/02 Python
PageFactory设计模式基于python实现
2020/04/14 Python
python读取yaml文件后修改写入本地实例
2020/04/27 Python
解决html5中的video标签ios系统中无法播放使用的问题
2020/08/10 HTML / CSS
GEOX鞋美国官方网站:意大利会呼吸的鞋
2017/07/12 全球购物
毕业生的自我鉴定
2013/10/29 职场文书
《问银河》教学反思
2014/02/19 职场文书
德语专业求职信
2014/03/12 职场文书
综合办公室主任岗位职责
2014/04/13 职场文书
青年志愿者活动方案
2014/08/17 职场文书
实习证明格式范文
2014/10/14 职场文书