2012-10-30 11 views
9

Próbuję użyć wykresów Matplotlib jako części gotowego do przesłania z aparatu , a publikacja wymaga użycia tylko czcionek typu 1 .Czcionki typu 1 z wykresami logów

Zauważyłem, że backend PDF z łatwością wyprowadza czcionki Type-1 dla prostych wykresów z liniowymi osiami Y, ale wyprowadza czcionki Type-3 dla logarytmicznych osi Y.

Użycie logarytmicznej skali powoduje użycie mathtext, który wydaje się być używać czcionek typu 3, prawdopodobnie ze względu na domyślne użycie notacji wykładniczej . Mogę użyć brzydkiego hacka, aby obejść to - używając pyplot.yticks() w celu wymuszenia tyknięć osi, aby nie używać wykładników - ale wymagałoby to przesunięcia obszaru wykresu, aby pomieścić duże etykiety (jak 10^6) lub pisanie osie takie jak 10, 100, 1K itd., aby pasowały.

Przetestowałem przykład poniżej z matplotlib głównej gałęzi dzień dzisiejszy, jak i 1.1.1, która produkuje takie samo zachowanie, więc nie wiem, że jest to błąd, prawdopodobnie tylko nieoczekiwane zachowanie.

#!/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) 

Czy ktoś wie, w jaki sposób można uzyskać czcionki Type 1 z osiami logu?

Dzięki!

+0

tylko dla świadomości, było to również wysłana na lista dyskusyjna mpl-users: http://matplotlib.1069221.n5.nabble.com/Type-1-fonts-with-log-graphs-tt39606.html – pelson

+0

S użyteczne odniesienia (brak odpowiedzi na to pytanie w nich): 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

Odpowiedz

6

Jest to kod używam dla kamer gotowe Zgłoszenia:

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) 

czcionki nie pojawi się aż do uruchomienia savefig

Przykład:

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

Po prostu wypróbowałem to z osią logu. Wydaje się, że działa dla mnie. Przepraszam, ta odpowiedź jest spóźniona. Miej nadzieję, że twoje zgłoszenie papieru poszło dobrze! Ja też tam byłem. – DrRobotNinja

4

Preferowaną metodą uzyskać czcionki Type 1 przez matplotlib wydaje się być użycie TeX do składu. Powoduje to, że oś jest wpisywana w domyślnej czcionce matematycznej, co jest zazwyczaj niepożądane, ale można tego uniknąć, używając poleceń TeX-a.

Krótko mówiąc, uważam, że to rozwiązanie:

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) 

Następnie wyniki w tej resulting image

Zainspirowany: https://stackoverflow.com/a/20709149/4189024 i http://wiki.scipy.org/Cookbook/Matplotlib/UsingTex