How to load .ttf file in matplotlib using mpl.rcParams?

匿名 (未验证) 提交于 2019-12-03 01:08:02

问题:

I have a matplotlib script that starts ...

import matplotlib as mpl import matplotlib.pyplot as plt import matplotlib.font_manager as fm  mpl.rcParams['xtick.labelsize']=16  ... 

I've used the command

fm.findSystemFonts() 

to get a list of the fonts on my system. I've discovered the full path to a .ttf file I'd like to use,

'/usr/share/fonts/truetype/anonymous-pro/Anonymous Pro BI.ttf' 

I've tried to use this font without success using the following commands

mpl.rcParams['font.family'] = 'anonymous-pro'   

and

mpl.rcParams['font.family'] = 'Anonymous Pro BI' 

which both return something like

/usr/lib/pymodules/python2.7/matplotlib/font_manager.py:1218: UserWarning: findfont: Font family ['anonymous-pro'] not found. Falling back to Bitstream Vera Sans 

Can I use the mpl.rcParams dictionary to set this font in my plots?

EDIT

After reading a bit more, it seems this is a general problem of determining the font family name from a .ttf file. Is this easy to do in linux or python ?

In addition, I've tried adding

mpl.use['agg'] mpl.rcParams['text.usetex'] = False 

without any success

回答1:

Specifying a font family:

If all you know is the path to the ttf, then you can discover the font family name using the get_name method:

import matplotlib as mpl import matplotlib.pyplot as plt import matplotlib.font_manager as font_manager  path = '/usr/share/fonts/truetype/msttcorefonts/Comic_Sans_MS.ttf' prop = font_manager.FontProperties(fname=path) mpl.rcParams['font.family'] = prop.get_name() fig, ax = plt.subplots() ax.set_title('Text in a cool font', size=40) plt.show() 

Specifying a font by path:

import matplotlib.pyplot as plt import matplotlib.font_manager as font_manager  path = '/usr/share/fonts/truetype/msttcorefonts/Comic_Sans_MS.ttf' prop = font_manager.FontProperties(fname=path) fig, ax = plt.subplots() ax.set_title('Text in a cool font', fontproperties=prop, size=40) plt.show() 


回答2:

You can use the fc-query myfile.ttf command to check the metadata information of a font according to the Linux font system (fontconfig). It should print you names matplotlib will accept. However the matplotlib fontconfig integration is rather partial right now, so I'm afraid it's quite possible you'll hit bugs and limitations that do not exist for the same fonts in other Linux applications.

(this sad state is hidden by all the hardcoded font names in matplotlib's default config, as soon as you start trying to change them you're in dangerous land)



回答3:

Whew I made it in under 100 lines, @nim this also explains in more detail how dangerous it is, some modifications change completely the behaviour of the font property and font size.

prerequisites: Matplotlib and a font folder at the same level of the script containing the ttf font-file calibri.ttf

But this is what I have for you as an easter egg:

import os import matplotlib import matplotlib.pyplot as plt import matplotlib.font_manager as fm from matplotlib import ft2font from matplotlib.font_manager import ttfFontProperty  __font_dir__ = os.path.join(os.path.dirname(__file__),"font") fpath = os.path.join(__font_dir__,'calibri.ttf')  font = ft2font.FT2Font(fpath) fprop = fm.FontProperties(fname=fpath)  ttfFontProp = ttfFontProperty(font)  fontsize=18  fontprop = fm.FontProperties(family='sans-serif',                             #name=ap.fontprop.name,                             fname=ttfFontProp.fname,                             size=fontsize,                             stretch=ttfFontProp.stretch,                             style=ttfFontProp.style,                             variant=ttfFontProp.variant,                             weight=ttfFontProp.weight)  matplotlib.rcParams.update({'font.size': fontsize,                         'font.family': 'sans-serif'})  fig, axis = plt.subplots()  axis.set_title('Text in a cool font',fontsize=fontsize,fontproperties=fontprop)  ax_right = axis.twinx()  axis.set_xlabel("some Unit",fontsize=fontsize,fontproperties=fontprop)  leftAxesName,rightAxesName = "left Unit", "right Unit"  axis.set_ylabel(leftAxesName,fontsize=fontsize,fontproperties=fontprop) if rightAxesName:     ax_right.set_ylabel(rightAxesName,fontsize=fontsize,fontproperties=fontprop)  for xLabel in axis.get_xticklabels():     xLabel.set_fontproperties(fontprop)     xLabel.set_fontsize(fontsize)  for yLabel in axis.get_yticklabels():     yLabel.set_fontproperties(fontprop)     yLabel.set_fontsize(fontsize)      yTickLabelLeft = ax_right.get_yticklabels()  for yLabel in yTickLabelLeft:     yLabel.set_fontproperties(fontprop)     yLabel.set_fontsize(fontsize)  axis.plot([0,1],[0,1],label="test")  nrow,ncol=1,1 handels,labels= axis.get_legend_handles_labels()  propsLeft=axis.properties()  propsRight=ax_right.properties()  print(propsLeft['title'],propsLeft['xlabel'],propsLeft['ylabel']) print(propsRight['ylabel'])  fig.set_tight_layout({'rect': [0, 0, 1, 0.95], 'pad': 0.05, 'h_pad': 1.5}) fig.tight_layout() fig.set_alpha(True)  leg_fig = plt.figure()  leg = leg_fig.legend(handels, labels, #labels = tuple(bar_names)    ncol=ncol, mode=None,     borderaxespad=0.,    loc='center',        # the location of the legend handles    handleheight=None,   # the height of the legend handles    #fontsize=9,         # prop beats fontsize    markerscale=None,    frameon=False,    prop=fontprop)  plt.show() 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!