2011-09-08 18 views
17

Hej,Diferencias entre Matplotlib Backend Agg y El Cairo

Me gustaría producir archivos PDF de alta calidad de parcelas matplotlib. Usando otro código, he producido una gran cantidad de números, los cuales trazo en una figura usando plt.imshow. Si ahora produzco un PDF usando plt.savefig, noto fuertes diferencias dependiendo de qué back-end utilizo. Lo que es más importante, los archivos producidos se vuelven enormes con el backend Agg o MacOSX, mientras que son razonablemente pequeños con Cairo (ver ejemplos a continuación). Por otro lado, el backend de El Cairo produce texto extraño junto con la representación de etiquetas TeX. Esto se ve horrible en el documento TeX. Por lo tanto, mi pregunta es doble:

  1. ¿Es posible producir pequeñas PDF (es decir, presumiblemente, sin interpolación de la imagen de la trama a una resolución más alta) usando el backend Agg?
  2. ¿Se puede cambiar algunos ajustes de texto para el backend Cairo tal que tiene una apariencia similar a TeX ordinaria (que es el caso para el backend Agg)

Aquí está un código de ejemplo para fines de prueba:

import matplotlib as mpl 
mpl.use("cairo") 

import numpy as np 
import matplotlib.pyplot as plt 
plt.rcParams['text.usetex'] = True 

data = np.random.rand(50, 50) 

plt.imshow(data, interpolation='nearest') 
plt.xlabel('X Label') 
plt.savefig('cairo.pdf') 

produce un PDF de 15Kb con una xlabel mal pintada.

import matplotlib as mpl 
mpl.use("agg") 

import numpy as np 
import matplotlib.pyplot as plt 
plt.rcParams['text.usetex'] = True 

data = np.random.rand(50, 50) 

plt.imshow(data, interpolation='nearest') 
plt.xlabel('X Label') 
plt.savefig('agg.pdf') 

produce un PDF de 986 Kb que se ve bien.

Probablemente debería agregar que uso matplotlib 1.0.1 con python 2.6.7 en OSX 10.6.8. En los comentarios, alguien pidió la salida de grep -a Font agg.pdf:

/Shading 6 0 R /Font 3 0 R >> 
<< /FontFile 16 0 R /Descent -285 /FontBBox [ -174 -285 1001 953 ] 
/StemV 50 /Flags 4 /XHeight 500 /Type /FontDescriptor 
/FontName /NimbusSanL-Regu /CapHeight 1000 /FontFamily (Nimbus Sans L) 
%!PS-AdobeFont-1.0: NimbusSanL-Regu 1.05a 
FontDirectory/NimbusSanL-Regu known{/NimbusSanL-Regu findfont dup/UniqueID known{dup 
/UniqueID get 5020902 eq exch/FontType get 1 eq and}{pop false}ifelse 
/FontType 1 def 
/FontMatrix [0.001 0 0 0.001 0 0 ]readonly def 
/FontName /NimbusSanL-Regu def 
/FontBBox [-174 -285 1001 953 ]readonly def 
/FontInfo 9 dict dup begin 
/BaseFont /NimbusSanL-Regu /Type /Font /Subtype /Type1 
/FontDescriptor 15 0 R /Widths 13 0 R /LastChar 255 /FirstChar 0 >> 
<< /FontFile 20 0 R /Descent -251 /FontBBox [ -34 -251 988 750 ] /StemV 50 
/Flags 4 /XHeight 500 /Type /FontDescriptor /FontName /CMR12 
/CapHeight 1000 /FontFamily (Computer Modern) /ItalicAngle 0 /Ascent 750 >> 
%!PS-AdobeFont-1.0: CMR12 003.002 
%Copyright: (<http://www.ams.org>), with Reserved Font Name CMR12. 
% This Font Software is licensed under the SIL Open Font License, Version 1.1. 
FontDirectory/CMR12 known{/CMR12 findfont dup/UniqueID known{dup 
/UniqueID get 5000794 eq exch/FontType get 1 eq and}{pop false}ifelse 
/FontType 1 def 
/FontMatrix [0.001 0 0 0.001 0 0 ]readonly def 
/FontName /CMR12 def 
/FontBBox {-34 -251 988 750 }readonly def 
/FontInfo 9 dict dup begin 
/Notice (Copyright \050c\051 1997, 2009 American Mathematical Society \050<http://www.ams.org>\051, with Reserved Font Name CMR12.) readonly def 
<< /BaseFont /CMR12 /Type /Font /Subtype /Type1 /FontDescriptor 19 0 R 
+0

No sé la respuesta, pero ¿podría escribir 'grep -a Font agg.pdf'? – unutbu

+0

Pongo la salida en la publicación principal, ya que la sección de comentarios es demasiado pequeña para contenerla. Gracias por hacer un esfuerzo! También sospeché que podría haber un problema con las fuentes. Básicamente trato de utilizar Computer Modern para hacer coincidir mi documento TeX. –

+0

Eche un vistazo a esta pregunta sobre matplotlib y el cairo, puede darle algunos consejos. http://stackoverflow.com/questions/2797525/matplotlib-pdf-export-uses-wrong-font –

Respuesta

5

Como sugiere steabert en los comentarios anteriores, una solución es la exportación de los gráficos en un formato diferente y luego convertirlo a PDF después. Ajuste de mi ejemplo de arriba, el flujo de trabajo podría ser algo como esto:

import os 
import matplotlib as mpl 
mpl.use("Agg") 

import numpy as np 
import matplotlib.pyplot as plt 
plt.rcParams['text.usetex'] = True 

data = np.random.rand(50, 50) 

plt.imshow(data, interpolation='nearest') 
plt.xlabel('X Label') 
plt.savefig('agg.eps') 

os.system('epspdf agg.eps agg.pdf') 

producir un fichero de 16 Kb, que se ve bien. Todavía hay una diferencia con los ejemplos presentados anteriormente: el uso de la (E) tubería PS parece ignorar la interpolación = la opción "más cercana", es decir, la imagen aparece borrosa en el PDF final. Afortunadamente, puedo vivir con eso, pero podría ser interesante analizar este tema.