为什么'matplotlib'找不到指定字体的特定字体权重?

zc0qhyus  于 2023-05-18  发布在  其他
关注(0)|答案(2)|浏览(156)

我遇到了麻烦,让matplotlib找到我知道安装在我的系统上的特定字体,并显示为可用根据matplotlib.font_manager。当我指定在我的图形中使用的特定权重时,我指定的字体不会被使用,链中的其他字体也不会被使用,而是使用链中更下游的字体。
我可以通过

import matplotlib
import matplotlib.font_manager as font_manager

# The backend doesn't matter
#matplotlib.use('agg')

font = {'family': 'sans-serif',
       'sans-serif': ['Open Sans', 'Lucida Grande', 'Avenir', 'Arial', 'sans-serif']}
matplotlib.rc('font', **font)
for font_weight in range(100, 1000, 100):
    matplotlib.rc('font', **{'weight': font_weight})
    print str(font_manager.FontProperties().get_weight()) + ": " + font_manager.FontProperties().get_name()

它产生

100: Open Sans
200: Open Sans
300: Arial
400: Arial
500: Arial
600: Open Sans
700: Open Sans
800: Open Sans
900: Open Sans

这与我在图中得到的结果相对应:对于“正常”,或者对于300到500之间的权重,我得到的不是Open Sans,而是Arial。
这是怎么回事?为什么matplotlib无法找到并使用系统中存在的字体?
FWIW,我可以检查字体管理员知道什么

import matplotlib
import matplotlib.font_manager as font_manager
import glob

the_files = font_manager.findSystemFonts(fontpaths=None)
# Using the_files = font_manager.OSXInstalledFonts() produces the same results
for font_name in ['Open Sans', 'Lucida Grande', 'Avenir', 'Arial']:
    print('')
    print('** ' + font_name)
    print("Names reported by font_manager for fonts in font_manager-found files with '" + font_name + "' in file name:")
    for the_file in the_files:
        if font_name.replace(' ', '').lower() in the_file.replace(' ', '').lower():
            the_props = font_manager.FontProperties(fname=the_file)
            print "\t" + the_props.get_name()

    print('')
    font_in_file_name = font_name.replace(' ', '')
    print("Files found through file system with '" + font_in_file_name + "' in file name:")
    for font_dir in ['/Users/Rax/Library/Fonts/', '/Library/Fonts/', '/System/Library/Fonts/']:
        for file in glob.glob(font_dir + font_in_file_name + '*.*'):
            print("\t" + file)

其确认存在所需字体

** Open Sans
Names reported by font_manager for fonts in font_manager-found files with 'Open Sans' in file name:
    Open Sans
    Open Sans
    Open Sans
    Open Sans
    Open Sans
    Open Sans
    Open Sans
    Open Sans
    Open Sans
    Open Sans

Files found through file system with 'OpenSans' in file name:
    /Users/Rax/Library/Fonts/OpenSans-Bold.ttf
    /Users/Rax/Library/Fonts/OpenSans-BoldItalic.ttf
    /Users/Rax/Library/Fonts/OpenSans-ExtraBold.ttf
    /Users/Rax/Library/Fonts/OpenSans-ExtraBoldItalic.ttf
    /Users/Rax/Library/Fonts/OpenSans-Italic.ttf
    /Users/Rax/Library/Fonts/OpenSans-Light.ttf
    /Users/Rax/Library/Fonts/OpenSans-LightItalic.ttf
    /Users/Rax/Library/Fonts/OpenSans-Regular.ttf
    /Users/Rax/Library/Fonts/OpenSans-Semibold.ttf
    /Users/Rax/Library/Fonts/OpenSans-SemiboldItalic.ttf

** Lucida Grande
Names reported by font_manager for fonts in font_manager-found files with 'Lucida Grande' in file name:

Files found through file system with 'LucidaGrande' in file name:
    /System/Library/Fonts/LucidaGrande.ttc

** Avenir
Names reported by font_manager for fonts in font_manager-found files with 'Avenir' in file name:

Files found through file system with 'Avenir' in file name:
    /System/Library/Fonts/Avenir Next Condensed.ttc
    /System/Library/Fonts/Avenir Next.ttc
    /System/Library/Fonts/Avenir.ttc

** Arial
Names reported by font_manager for fonts in font_manager-found files with 'Arial' in file name:
    Arial
    Arial Black
    Arial
    Arial
    Arial Narrow
    Arial Narrow
    Arial Narrow
    Arial Rounded MT Bold
    Arial
    Arial Unicode MS
    Arial Narrow

Files found through file system with 'Arial' in file name:
    /Library/Fonts/Arial Black.ttf
    /Library/Fonts/Arial Bold Italic.ttf
    /Library/Fonts/Arial Bold.ttf
    /Library/Fonts/Arial Italic.ttf
    /Library/Fonts/Arial Narrow Bold Italic.ttf
    /Library/Fonts/Arial Narrow Bold.ttf
    /Library/Fonts/Arial Narrow Italic.ttf
    /Library/Fonts/Arial Narrow.ttf
    /Library/Fonts/Arial Rounded Bold.ttf
    /Library/Fonts/Arial Unicode.ttf
    /Library/Fonts/Arial.ttf
    /Library/Fonts/ArialHB.ttc

我运行的是OSX 10.9.1,正如上面的代码所指出的,使用OSXInstalledFonts而不是findSystemFonts会产生相同的结果。

sirbozc5

sirbozc51#

当你同时输出the_props._file时会发生什么?

import matplotlib
import matplotlib.font_manager as font_manager
import glob

the_files = font_manager.findSystemFonts(fontpaths=None)
# Using the_files = font_manager.OSXInstalledFonts() produces the same results
for font_name in ['Open Sans', 'Lucida Grande', 'Avenir', 'Arial']:
    print('')
    print('** ' + font_name)
    print("Names reported by font_manager for fonts in font_manager-found files with '" + font_name + "' in file name:")
    for the_file in the_files:
        if font_name.replace(' ', '').lower() in the_file.replace(' ', '').lower():
            the_props = font_manager.FontProperties(fname=the_file)
            print "\t" + the_props.get_name(), 
            print '\t\t', the_props._file

    print('')
    font_in_file_name = font_name.replace(' ', '')
    print("Files found through file system with '" + font_in_file_name + "' in file name:")
    for font_dir in ['/Users/Rax/Library/Fonts/', '/Library/Fonts/', '/System/Library/Fonts/']:
        for file in glob.glob(font_dir + font_in_file_name + '*.*'):
            print("\t" + file)

对我来说输出

** Open Sans
Names reported by font_manager for fonts in font_manager-found files with 'Open Sans' in file name:

Files found through file system with 'OpenSans' in file name:

** Lucida Grande
Names reported by font_manager for fonts in font_manager-found files with 'Lucida Grande' in file name:

Files found through file system with 'LucidaGrande' in file name:
    /System/Library/Fonts/LucidaGrande.ttc

** Avenir
Names reported by font_manager for fonts in font_manager-found files with 'Avenir' in file name:

Files found through file system with 'Avenir' in file name:
    /System/Library/Fonts/Avenir Next Condensed.ttc
    /System/Library/Fonts/Avenir Next.ttc
    /System/Library/Fonts/Avenir.ttc

** Arial
Names reported by font_manager for fonts in font_manager-found files with 'Arial' in file name:
    Arial       /Library/Fonts/Arial Bold Italic.ttf
    Arial Black         /Library/Fonts/Arial Black.ttf
    Arial       /Library/Fonts/Microsoft/Arial.ttf
    Arial       /Library/Fonts/Microsoft/Arial Italic.ttf
    Arial       /Library/Fonts/Arial Italic.ttf
    Arial       /Library/Fonts/Microsoft/Arial Bold Italic.ttf
    Arial       /Library/Fonts/Arial.ttf
    Arial Narrow        /Library/Fonts/Arial Narrow.ttf
    Arial Narrow        /Library/Fonts/Arial Narrow Bold.ttf
    Arial Narrow        /Library/Fonts/Arial Narrow Italic.ttf
    Arial       /Library/Fonts/Microsoft/Arial Bold.ttf
    Arial Rounded MT Bold       /Library/Fonts/Arial Rounded Bold.ttf
    Arial       /Library/Fonts/Arial Bold.ttf
    Arial Unicode MS        /Library/Fonts/Arial Unicode.ttf
    Arial Narrow        /Library/Fonts/Arial Narrow Bold Italic.ttf

Files found through file system with 'Arial' in file name:
    /Library/Fonts/Arial Black.ttf
    /Library/Fonts/Arial Bold Italic.ttf
    /Library/Fonts/Arial Bold.ttf
    /Library/Fonts/Arial Italic.ttf
    /Library/Fonts/Arial Narrow Bold Italic.ttf
    /Library/Fonts/Arial Narrow Bold.ttf
    /Library/Fonts/Arial Narrow Italic.ttf
    /Library/Fonts/Arial Narrow.ttf
    /Library/Fonts/Arial Rounded Bold.ttf
    /Library/Fonts/Arial Unicode.ttf
    /Library/Fonts/Arial.ttf
    /Library/Fonts/ArialHB.ttc

我在我的电脑上尝试了这个,我没有Open Sans或Avenir,但Lucida Grande出现在“通过文件系统找到的文件..”循环中。然而,当我尝试一个情节,它看起来像Arial:http://nbviewer.ipython.org/gist/olgabot/8099973
我认为matplotlib正在寻找/Library/Fonts中的字体,而不是/System/Library/Fonts/Users/.../Library/Fonts。所以我的建议是,如果可以的话,把.ttf文件复制到/Library/Fonts上。如果不是,那么this question指定如何从完整路径加载字体。
看起来.ttc字体文件也有一些问题,所以我会尽可能坚持使用.ttf

1aaf6o9v

1aaf6o9v2#

我建议使用以下代码:

import matplotlib.font_manager
matplotlib.font_manager.fontManager.ttflist

输出是一个列表,其中每个条目都遵循以下结构

FontEntry(fname='/System/Library/Fonts/Supplemental/Arial Bold Italic.ttf', name='Arial', style='italic', variant='normal', weight=700, stretch='normal', size='scalable'),

在输出列表中,检查matplotlib要求您如何调用感兴趣的字体(这里:接下来,检查每个宽度是否存储在具有相同名称但宽度不同的不同字体文件(例如.ttf)中。
通常,具有多种宽度的字体可以以两种不同的方式存储。每个宽度可以存储在一个.ttf文件中,或者每个宽度存储在一个.ttf文件中。根据我的经验,Matplotlib似乎无法处理在一个文档中存储所有宽度。

相关问题