2016-01-20 50 views
0

我已經編寫了這些代碼,它將生成許多輪廓圖,每個輪廓圖對應一個文本文件。我有多個文本文件。目前,我能夠以png格式分別生成所有圖像,沒有任何問題。 當我嘗試將圖像保存爲pdf文件時,它只保存循環中生成的最後一張圖像。我嘗試使用PdfPages包。這個問題與我之前發佈的問題類似,但帶有不同的問題。 Similar將循環中生成的輪廓圖像保存爲一個pdf文件(最好每頁2個圖像)

問題:我想能夠從python自動生成所有圖像爲一個pdf文件。因此,例如。如果我有100個文本文件,那麼我想將所有的100個圖像保存到一個PDF文件中。理想情況下,我想將2個圖像保存在pdf文件的單個頁面中。 SO有一些問題,但我找不到適合我的問題的解決方案。由於我有很多情況需要生成圖像,因此我想將它們保存爲一個pdf文件,因爲它更容易分析。我將不勝感激任何建議/建議來幫助我解決這個問題。

這是鏈接的示例文本文件Sample Text GES

from __future__ import print_function 
import numpy as np 
from matplotlib import pyplot as plt 
from scipy.interpolate import griddata 
from matplotlib.backends.backend_pdf import PdfPages 
path = 'location of the text files' 
FT_init = 5.4311 
delt = 0.15 
TS_init = 140 
dj_length = 2.4384 

def streamfunction2d(y,x,Si_f,q):  
    with PdfPages('location of the generated pdf') as pdf: 
     Stf= plt.contour(x,y,Si_f,20) 
     Stf1 = plt.colorbar(Stf) 
     plt.clabel(Stf,fmt='%.0f',inline=True) 
     plt.figtext(0.37,0.02,'Flowtime(s)',style= 'normal',alpha=1.0) 
     plt.figtext(0.5,0.02,str(q[p]),style= 'normal',alpha=1.0) 
     plt.title('Streamfunction_test1') 
     plt.hold(True)  
     plt.tight_layout() 
     pdf.savefig() 

     path1 = 'location where the image is saved' 
     image = path1+'test_'+'Stream1_'+str((timestep[p]))+'.png' 
     plt.savefig(image)  
     plt.close() 

timestep = np.linspace(500,600,2) 
flowtime = np.zeros(len(timestep)) 
timestep = np.array(np.round(timestep),dtype = 'int') 
############################################################################### 
for p in range(len(timestep)): 
     if timestep[p]<TS_init: 
      flowtime[p] = 1.1111e-01 
     else: 
      flowtime[p] = (timestep[p]-TS_init)*delt+FT_init 
     q = np.array(flowtime) 

     timestepstring=str(timestep[p]).zfill(4) 
     fname = path+"ddn150AE-"+timestepstring+".txt" 
     f = open(fname,'r') 
     data = np.loadtxt(f,skiprows=1) 
     data = data[data[:, 1].argsort()] 
     data = data[np.logical_not(data[:,11]== 0)]                 
     Y = data[:,2] # Assigning Y to column 2 from the text file 
     limit = np.nonzero(Y==dj_length)[0][0] 
     Y = Y[limit:] 

     Vf = data[:,11] 
     Vf = Vf[limit:] 
     Tr = data[:,9] 
     Tr = Tr[limit:] 

     X = data[:,1] 
     X = X[limit:] 
     Y = data[:,2] 
     Y = Y[limit:] 
     U = data[:,3] 
     U = U[limit:] 
     V = data[:,4] 
     V = V[limit:] 
     St = data[:,5] 
     St = St[limit:] 
     ###########################################################################  

     ## Using griddata for interpolation from Unstructured to Structured data 
     # resample onto a 300x300 grid   
     nx, ny = 300,300 

     # (N, 2) arrays of input x,y coords and dependent values 
     pts = np.vstack((X,Y)).T 
     vals = np.vstack((Tr)) 
     vals1 = np.vstack((St)) 

     # The new x and y coordinates for the grid 
     x = np.linspace(X.min(), X.max(), nx) 
     y = np.linspace(Y.min(), Y.max(), ny) 
     r = np.meshgrid(y,x)[::-1] 

     # An (nx * ny, 2) array of x,y coordinates to interpolate at 
     ipts = np.vstack(a.ravel() for a in r).T 

     Si = griddata(pts, vals1, ipts, method='linear') 
     print(Ti.shape,"Ti_Shape") 
     Si_f = np.reshape(Si,(len(y),len(x))) 
     print(Si_f.shape,"Streamfunction Shape")   
     Si_f = np.transpose(Si_f)   
     streamfunction2d(y,x,Si_f,q) 

回答

2

編輯:正如你所說matplotlib大概是能夠通過自身使用PdfPages函數來處理一切。見this related answer。我原來的答案是黑客。

我認爲你的代碼中的錯誤是你每次通過循環時都要創建另一個PdfPage對象。我的建議是將PdfPage對象作爲參數添加到streamfunction2d函數中,並在循環之前一次性創建PdfPage對象(使用中的with語句似乎是個好主意)。

例子:

def streamfunction2d(y,x,Si_f,q,pdf):  
    # (...) 
    pdf.savefig(plt.gcf()) 

with PdfPages('output.pdf') as pdf: 
    for p in range(len(timestep)): 
     # (...) 
     streamfunction2d(y,x,Si_f,q,pdf) 

原來的答覆: 下面是一個使用pdfunite軟件一個快速和骯髒的解決方案。

from matplotlib import pyplot as plt 
import numpy as np 
import subprocess 
import os 

X = np.linspace(0,1,100) 
for i in range(10): 
    # random plot 
    plt.plot(X,np.cos(i*X)) 

    # Save each figure as a pdf file. 
    plt.savefig("page_{:0}.pdf".format(i)) 
    plt.clf() 

# Calling pdfunite to merge all the pages 
subprocess.call("pdfunite page_*.pdf united.pdf",shell=True) 

# Removing temporary files 
for i in range(10): 
    os.remove("page_{:0}.pdf".format(i)) 

它採用了兩件事情:

  • 可以使用matplotlib的savefig命令保存您的數字爲PDF。
  • 您可以使用subprocess庫調用其他程序。我用pdfunite來合併所有頁面。確保它在您的機器上可用!

如果你想有多個圖形,你可以使用子圖。

或者,您可以使用另一個python庫(如pyPDF)來合併頁面,但它需要稍微多一點的代碼。下面是一個(未測試)實施例:

from matplotlib import pyplot as plt 
import numpy as np 
from pyPdf import PdfFileWriter, PdfFileReader 

# create an empty pdf file 
output = PdfFileWriter() 

X = np.linspace(0,1,100) 
for i in range(10): 
    # random plot 
    plt.plot(X,np.cos(i*X)) 

    # Save each figure as a pdf file. 
    fi = "page_{:0}.pdf".format(i) 
    plt.savefig(fi) 
    plt.clf() 

    # add it to the end of the output 
    input = PdfFileReader(file(fi, "rb")) 
    output.addPage(input.getPage(0)) 

# Save the resulting pdf file. 
outputStream = file("document-output.pdf", "wb") 
output.write(outputStream) 
+0

在我的代碼,我添加image1的= PATH1 + '測試_' + '流1 _' + STR((時間步長[P]))+ 'PDF文件。',然後使用PLT。 savefig(圖像1)。現在它正在保存多個pdf,並且合併功能不起作用。您能否將您的解決方案添加到我的代碼中?謝謝 –

+0

如果你有多個文件,你就在正確的軌道上:你現在只需要合併。 (你可以通過在我的示例代碼中添加'os.remove'來刪除所有的頁面pdf,然後進行清理)。你使用哪種合併方法?什麼是錯誤信息? (你是否安裝了'pdfunite'或者'pypdf'庫?) – Geeklhem

+0

我添加了一個可能的解決方案,它只依賴於matplotib。 – Geeklhem