2012-10-30 6 views
9

Sto provando a utilizzare i grafici Matplotlib come parte di una presentazione pronta per la fotocamera e la casa editrice richiede l'uso di font Type 1 .Caratteri Type 1 con log graph

Ho constatato che il back-end PDF emette felicemente Type-1 caratteri per semplici grafici con assi Y lineari, ma uscite di tipo-3 caratteri per logaritmica Y assi.

Utilizzando una yscale logaritmica incorre l'uso di mathtext, che sembra uso font Type 3, presumibilmente a causa dell'uso di default esponenziale notazione. Posso usare un brutto schermaggio per aggirare questo - usando pyplot.yticks() per forzare le zecche degli assi a non usare esponenti - ma ciò richiederebbe lo spostamento della regione di trama per contenere etichette grandi (come 10^6) o scrivere gli assi come 10, 100, 1K, ecc. così si adattano.

Ho testato l'esempio di seguito con il maestro ramo matplotlib come di oggi, così come 1.1.1, che produce lo stesso comportamento, in modo da non so che questo è un bug, probabilmente solo comportamento inaspettato.

#!/usr/bin/env python 
# Simple program to test for type 1 fonts. 
# Generate a line graph w/linear and log Y axes. 

from matplotlib import rc, rcParams 

rc('font',**{'family':'sans-serif','sans-serif':['Helvetica']}) 
#rc('font',**{'family':'sans-serif','sans-serif':['computer modern sans serif']}) 

# These lines are needed to get type-1 results: 
# http://nerdjusttyped.blogspot.com/2010/07/type-1-fonts-and-matplotlib-figures.html 
rcParams['ps.useafm'] = True 
rcParams['pdf.use14corefonts'] = True 
rcParams['text.usetex'] = False 

import matplotlib.pyplot as plt 

YSCALES = ['linear', 'log'] 

def plot(filename, yscale): 
    plt.figure(1) 
    xvals = range(1, 2) 
    yvals = xvals 
    plt.plot(xvals, yvals) 
    plt.yscale(yscale) 
    plt.savefig(filename + '.pdf') 

if __name__ == '__main__': 
    for yscale in YSCALES: 
     plot('linegraph-' + yscale, yscale) 

Qualcuno sa un modo pulito per ottenere font Type 1 con gli assi del registro?

Grazie!

+0

Proprio per la consapevolezza, questo è stato anche pubblicato su la mailinglist degli utenti mpl: http://matplotlib.1069221.n5.nabble.com/Type-1-fonts-with-log-graphs-tt39606.html – pelson

+0

S Alcuni riferimenti utili (nessuna risposta a questa domanda): http://matplotlib.1069221.n5.nabble.com/Type-1-font-in-figures-needed-td10294.html & http: //nerdjusttyped.blogspot .co.uk/2010/07/type-1-fonts-and-matplotlib-figures.html – pelson

risposta

6

Questo è il codice che uso per la macchina fotografica pronta mezzi:

from matplotlib import pyplot as plt 

def SetPlotRC(): 
    #If fonttype = 1 doesn't work with LaTeX, try fonttype 42. 
    plt.rc('pdf',fonttype = 1) 
    plt.rc('ps',fonttype = 1) 

def ApplyFont(ax): 

    ticks = ax.get_xticklabels() + ax.get_yticklabels() 

    text_size = 14.0 

    for t in ticks: 
     t.set_fontname('Times New Roman') 
     t.set_fontsize(text_size) 

    txt = ax.get_xlabel() 
    txt_obj = ax.set_xlabel(txt) 
    txt_obj.set_fontname('Times New Roman') 
    txt_obj.set_fontsize(text_size) 

    txt = ax.get_ylabel() 
    txt_obj = ax.set_ylabel(txt) 
    txt_obj.set_fontname('Times New Roman') 
    txt_obj.set_fontsize(text_size) 

    txt = ax.get_title() 
    txt_obj = ax.set_title(txt) 
    txt_obj.set_fontname('Times New Roman') 
    txt_obj.set_fontsize(text_size) 

I font non appariranno finché non si esegue savefig

Esempio:

import numpy as np 

SetPlotRC() 

t = np.arange(0, 2*np.pi, 0.01) 
y = np.sin(t) 

plt.plot(t,y) 
plt.xlabel("Time") 
plt.ylabel("Signal") 
plt.title("Sine Wave") 

ApplyFont(plt.gca()) 
plt.savefig("sine.pdf") 
+1

L'ho appena provato con un asse logaritmico. Sembra funzionare per me. Spiacente, questa risposta è così in ritardo. Spero che la tua presentazione cartacea sia andata bene! Ci sono stato anche io. – DrRobotNinja

4

Il metodo preferito per ottenere font Type 1 tramite matplotlib sembra essere quello di usare TeX per la composizione. In questo modo, viene rappresentato dall'asse nel tipo di carattere matematico predefinito, che è in genere indesiderato ma che può essere evitato utilizzando i comandi TeX.

Per farla breve, ho trovato questa soluzione:

import matplotlib.pyplot as mp 
import numpy as np 

mp.rcParams['text.usetex'] = True #Let TeX do the typsetting 
mp.rcParams['text.latex.preamble'] = [r'\usepackage{sansmath}', r'\sansmath'] #Force sans-serif math mode (for axes labels) 
mp.rcParams['font.family'] = 'sans-serif' # ... for regular text 
mp.rcParams['font.sans-serif'] = 'Helvetica, Avant Garde, Computer Modern Sans serif' # Choose a nice font here 

fig = mp.figure() 
dim = [0.1, 0.1, 0.8, 0.8] 

ax = fig.add_axes(dim) 
ax.text(0.001, 0.1, 'Sample Text') 
ax.set_xlim(10**-4, 10**0) 
ax.set_ylim(10**-2, 10**2) 
ax.set_xscale("log") 
ax.set_yscale("log") 
ax.set_xlabel('$\mu_0$ (mA)') 
ax.set_ylabel('R (m)') 
t = np.arange(10**-4, 10**0, 10**-4) 
y = 10*t 

mp.plot(t,y) 

mp.savefig('tmp.png', dpi=300) 

si traduce poi in questo resulting image

Ispirato da: https://stackoverflow.com/a/20709149/4189024 e http://wiki.scipy.org/Cookbook/Matplotlib/UsingTex