2013-05-15 12 views
8

Ho uno script matplotlib che inizia ...Come caricare il file .ttf in matplotlib usando mpl.rcParams?

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

mpl.rcParams['xtick.labelsize']=16 
... 

Ho usato il comando

fm.findSystemFonts() 

per ottenere un elenco dei caratteri sul mio sistema. Ho scoperto il percorso completo di un file .ttf mi piacerebbe usare,

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

Ho provato ad utilizzare questo tipo di carattere, senza successo utilizzando i seguenti comandi

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

e

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

cui entrambi tornare qualcosa come

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

Posso usare il dizionario mpl.rcParams per impostare questo carattere nei miei grafici?

EDIT

Dopo aver letto un po 'di più, sembra che questo è un problema generale di determinare il nome della famiglia di font da un file .ttf. È così facile da fare in linux o python?

Inoltre, ho provato ad aggiungere

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

senza alcun successo

risposta

11

Specifica di una famiglia di caratteri:

Se tutto quello che sai è il percorso per la TTF, allora si può scoprire il nome della famiglia di font usando il metodo get_name:

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() 

specificare un tipo di carattere in base al percorso:

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() 
+0

grazie. Ho visto la soluzione in [questo] (http://stackoverflow.com/questions/12790284/why-doesnt-matplotlib-use-the-ttf-font-that-i-provide?rq=1) post. Tuttavia, mi piacerebbe cambiare il carattere di tutto il testo sul grafico senza aggiornare ogni comando che produce testo e/o aggiungere comandi per cambiare il testo delle etichette degli assi. Ecco perché preferirei usare mpl.rcParams se possibile. –

+0

che fa il trucco. Grazie! –

+0

Freddo. Grazie per la risposta dettagliata. Aiuta molto! –

3

È possibile utilizzare il comando fc-query myfile.ttf per controllare le informazioni dei metadati di un tipo di carattere in base al sistema di font Linux (fontconfig). Dovrebbe stamparti i nomi che Matplotlib accetterà. Tuttavia l'integrazione di matplotlib fontconfig è piuttosto parziale in questo momento, quindi temo che sia abbastanza probabile che si verifichino bug e limitazioni che non esistono per gli stessi font in altre applicazioni Linux.

(questo stato triste è nascosto da tutti i nomi dei font hardcoded nella configurazione di default di matplotlib, non appena si inizia a cercare di cambiarli siete in terra pericoloso)

1

Accidenti ho fatto in meno di 100 linee, @nim questo spiega anche in modo più dettagliato quanto sia pericoloso, alcune modifiche cambiano completamente il comportamento della proprietà del font e della dimensione del font.

prerequisiti: Matplotlib e una cartella font allo stesso livello dello script contenente il file di font ttf calibri.TTF

Ma questo è quello che ho per voi come un uovo di Pasqua:

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() 
Problemi correlati