2013-10-24 88 views
0

我需要將matplotlib數據保存爲pdf。我遵循Matplotlib howto上的說明,除了不是顯示結果,而是將它保存爲pdf。奇怪的是,pdf畫布不受畫布大小調整的影響。相反,保存到PNG正常工作與放大的畫布。邊界框問題保存爲pdf

import matplotlib.pyplot as plt 
import matplotlib.transforms as mtransforms 
fig = plt.figure() 
ax = fig.add_subplot(111) 
ax.plot(range(10)) 
ax.set_yticks((2,5,7)) 
labels = ax.set_yticklabels(('really, really, really', 'long', 'labels')) 

def on_draw(event): 
    bboxes = [] 
    for label in labels: 
     bbox = label.get_window_extent() 
     # the figure transform goes from relative coords->pixels and we 
     # want the inverse of that 
     bboxi = bbox.inverse_transformed(fig.transFigure) 
     bboxes.append(bboxi) 

    # this is the bbox that bounds all the bboxes, again in relative 
    # figure coords 
    bbox = mtransforms.Bbox.union(bboxes) 
    if fig.subplotpars.left < bbox.width: 
     # we need to move it over 
     fig.subplots_adjust(left=1.1*bbox.width) # pad a little 
     fig.canvas.draw() 
    return False 

fig.canvas.mpl_connect('draw_event', on_draw) 

plt.savefig("test.pdf", format="pdf") 

screen capture of pdf image

UPDATE

plt.tight_layout() 

會爲標題和軸蜱,但忽略圖例如果它被放置在框架的外側,如在下面的圖中。請注意,我將圖例放在圖的右側。

import matplotlib.pyplot as plt 
fig = plt.figure() 
ax = fig.add_subplot(111) 
p1, = plt.plot(range(10)) 
p2, = plt.plot(range(10,0,-1)) 
ax.set_yticks((2,5,7)) 
plt.labels = ax.set_yticklabels(('really, really, really', 'long', 'labels')) 
plt.legend([p2, p1], ["line with a loong label", "line with an even longer label, dude!"],\ 
      loc="center left", bbox_to_anchor=(1, 0.5)) 
plt.tight_layout() 
plt.savefig("test.pdf", format="pdf") 
+0

看到http://stackoverflow.com/questions/15882249/matplotlib-aligning-y-ticks-to-the-left/15883858#15883858 – tacaswell

+0

和http: //stackoverflow.com/questions/18769870/matplotlib-wxpython-not-sizing-correctly-with-legend/18771068#18771068 – tacaswell

回答

2

一個可能的黑客是通過

plt.tight_layout(rect = [0, 0, 0.4, 1]) 

更換plt.tight_layout(),但不是很不錯。什麼對我的作品被使用參數bbox_inches

plt.savefig("test.pdf", format="pdf", bbox_inches = 'tight') 
+0

'bbox_inches ='tight''的缺點是你失去了對最終數字有多大的控制。如果您嘗試將標籤的字體大小與嵌入數字的文字相匹配,這可能非常重要。 – tacaswell

+0

@tcaswell好點。這是一個警告,但它不會使大多數情況下的方法失效。 – dmvianna

-1

使用可以嘗試這個例子和解決您的問題。

import matplotlib.pyplot as plt 
import numpy as np 
sin, cos = np.sin, np.cos 

fig = plt.figure(frameon = False) 
fig.set_size_inches(5, 8) 
ax = plt.Axes(fig, [0., 0., 1., 1.],) 
ax.set_axis_off() 
fig.add_axes(ax) 

x = np.linspace(-4, 4, 20) 
y = np.linspace(-4, 4, 20) 
X, Y = np.meshgrid(x, y) 
deg = np.arctan(Y**3-3*Y-X) 
plt.quiver(X, Y, cos(deg), sin(deg), pivot = 'tail', units = 'dots', color = 'red',) 
plt.savefig('/tmp/test.png', dpi = 200) 

您可以通過設置數字使產生的圖像1000x1600像素爲5×8英寸

fig.set_size_inches(5, 8) 
and saving with DPI = 200: 

plt.savefig('/tmp/test.png', dpi = 200) 
The code to remove the border was taken from here. 

(The image posted above is not to scale since 1000x1600 is rather large). 
+0

該問題與定義或保存到PNG無關。問題是保存到__pdf__。 – dmvianna