【问题标题】:Save contour images generated in a loop as a single pdf file (2 images per page preferably)将循环生成的轮廓图像保存为单个 pdf 文件(最好每页 2 个图像)
【发布时间】:2016-01-20 17:41:39
【问题描述】:

我编写了这段代码,它将生成许多等高线图,每个等高线图对应于一个文本文件。我有多个文本文件。目前,我能够以 png 格式单独生成所有图像,没有任何问题。 当我尝试将图像保存为 pdf 文件时,它只保存循环中生成的最后一张图像。我尝试使用 PdfPages 包。这个问题与我之前发布的问题相似,但有一个不同的问题。 Similar

问题:我希望能够从 python 自动将所有图像生成到单个 pdf 文件中。所以例如。如果我有 100 个文本文件,那么我想将所有 100 个图像保存到一个 pdf 文件中。理想情况下,我想在 pdf 文件的单个页面中保存 2 个图像。 SO中有一些关于此的问题,但我找不到适合我的问题的解决方案。由于我有很多情况需要生成图像,因此我想将它们保存为单个 pdf 文件,因为这样更容易分析它们。我将不胜感激任何可以帮助我解决此问题的建议/建议。

这是示例文本文件的链接Sample Text 哥们

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) 

【问题讨论】:

    标签: python matplotlib interpolation contour


    【解决方案1】:

    编辑:正如你提到的,matplotlib 可能能够使用PdfPages 函数自行处理所有事情。见this related answer。我原来的答案是一个黑客。

    我认为您的代码中的错误是您每次通过循环时都在创建另一个 PdfPage 对象。我的建议是将PdfPage 对象作为参数添加到您的streamfunction2d 函数中,并在循环之前一劳永逸地创建PdfPage 对象(使用with 中的documentation 语句似乎很好想法)。

    例子:

    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)
    

    【讨论】:

    • 在我的代码中,我添加了 image1 = path1+'test_'+'Stream1_'+str((timestep[p]))+'.pdf' 然后使用 plt.savefig(image1)。现在它正在保存多个 pdf 并且合并功能不起作用。您能否将您的解决方案添加到我的代码中?谢谢
    • 如果你有多个文件,你就在正确的轨道上:你现在只需要合并。 (您可以通过使用os.remove 删除所有一页pdf 来清理,正如我在示例代码中添加的那样)。您使用了哪种合并方法?错误信息是什么? (您是否安装了pdfunitepypdf 库?)
    • 我添加了一个可能的解决方案,它只依赖于你最初想要的 matplotib。
    • 谢谢 Geeklhem。我现在知道如何使用不同的技术来完成我们的任务。我会尝试你的新解决方案。顺便说一句,您的 pdf unite 解决方案有效,但是当它合并 pdf 时,文件没有按顺序合并。如果有办法做到这一点,请告诉我。我会接受你的回答。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 2013-07-01
    • 2012-11-13
    • 1970-01-01
    • 1970-01-01
    • 2014-01-03
    • 2019-11-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多