Agg和Cairo之间的Matplotlib后端差异 [英] Matplotlib Backend Differences between Agg and Cairo

查看:173
本文介绍了Agg和Cairo之间的Matplotlib后端差异的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嘿,

我想从matplotlib图中生成高质量的PDF.使用其他代码,我生成了大量数字,并使用plt.imshow在图中绘制了这些数字.如果现在我使用plt.savefig生成PDF,我会发现差异很大,具体取决于所使用的后端.最重要的是,生成的文件在Agg或MacOSX后端变得很大,而在Cairo中则很小(请参见下面的示例).另一方面,Cairo后端与标签的TeX渲染一起生成奇怪的文本.在TeX文档中,这看起来很糟糕.因此,我的问题是双重的:

I'd like to produce high quality PDFs from matplotlib plots. Using other code, I have produced a large array of numbers, which I plot in a figure using plt.imshow. If I now produce a PDF using plt.savefig, I notice strong differences depending on which backend I use. Most importantly, the produced files get huge with the Agg or MacOSX backend, while they are reasonably small with Cairo (see examples below). On the other hand, the Cairo backend produces weird text in conjunction with the TeX rendering of labels. This looks awful in the TeX document. My question is therefore twofold:

  1. 是否可以使用Agg后端生成小的PDF(即大概无需将光栅图像插值到更高的分辨率)?
  2. 是否可以更改Cairo后端的某些文本设置,使其看起来类似于普通的TeX(Agg后端就是这种情况)

以下是用于测试目的的示例代码:

Here is some example code for test purposes:

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

产生的15Kb PDF带有不好看的xlabel.

produces a PDF of 15Kb with a bad looking xlabel.

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

生成的986Kb PDF看起来不错.

produces a PDF of 986Kb which looks good.

我可能应该补充一点,我在OSX 10.6.8上将matplotlib 1.0.1与python 2.6.7一起使用.在评论中,有人要求输出grep -a Font agg.pdf:

I should probably add that I use matplotlib 1.0.1 with python 2.6.7 on OSX 10.6.8. In the comments, someone requested the output of 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

推荐答案

正如steabert在上面的评论中所建议的那样,一种解决方法是将图形导出为其他格式,然后再将其转换为PDF.从上面调整我的示例,工作流程可能如下所示:

As suggested by steabert in the comments above, a workaround is exporting the graphics in a different format and then convert it to PDF afterwards. Adjusting my example from above, the workflow could look something like this:

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

产生一个16 Kb的文件,看起来不错.上面显示的示例仍然有一个区别:使用(E)PS管道似乎忽略了插值=最近"选项,即图像在最终PDF中显得模糊.幸运的是,我可以接受,但是研究这个问题可能会很有趣.

producing a file of 16 Kb which looks good. There is still one difference to the examples presented above: Using the (E)PS pipeline seems to ignore the interpolation='nearest' option, i.e. the image appears blurry in the final PDF. Luckily, I can live with that, but it might be interesting to look into this issue.

这篇关于Agg和Cairo之间的Matplotlib后端差异的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆