2013-10-24 2 views
0

Мне нужно сохранить фигуры matplotlib в pdf. Я следую инструкциям на Matplotlib howto, за исключением того, что вместо отображения результатов я сохраняю его в 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

ОБНОВЛЕНИЕ

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() с

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

, но это не очень хороший. То, что работает для меня использует аргумент 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