将循环生成的轮廓图像保存为单个 pdf 文件(最好每页 2 个图像)
Save contour images generated in a loop as a single pdf file (2 images per page preferably)
我编写了这段代码,它将生成许多等高线图,每个等高线图对应一个文本文件。我有多个文本文件。目前,我能够毫无问题地以 png 格式单独生成所有图像。
当我尝试将图像保存为 pdf 文件时,它只保存在 loop.I 中尝试使用 PdfPages 包生成的最后一张图像。这个问题与我之前发布的问题类似,但问题不同。 Similar
问题:我希望能够从 python 自动将所有图像生成到一个 pdf 文件中。所以例如。如果我有 100 个文本文件,那么我想将所有 100 个图像保存到一个 pdf file.Also 理想情况下,我想在 pdf 文件的单个页面中保存 2 个图像。 SO 中有一些关于此的问题,但我找不到适合我的问题的解决方案。由于我有很多案例需要生成图像,所以我想将它们保存为单个 pdf 文件,因为这样更容易分析它们。如果有 suggestions/advice 帮助我,我将不胜感激。
这是示例文本文件 link 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)
Edit :正如您提到的,matplotlib 可能能够使用 PdfPages
function. See this related answer 自行处理所有事情。我原来的答案是 hack。
我认为您的代码中的错误是您每次执行循环时都在创建另一个 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)
我编写了这段代码,它将生成许多等高线图,每个等高线图对应一个文本文件。我有多个文本文件。目前,我能够毫无问题地以 png 格式单独生成所有图像。 当我尝试将图像保存为 pdf 文件时,它只保存在 loop.I 中尝试使用 PdfPages 包生成的最后一张图像。这个问题与我之前发布的问题类似,但问题不同。 Similar
问题:我希望能够从 python 自动将所有图像生成到一个 pdf 文件中。所以例如。如果我有 100 个文本文件,那么我想将所有 100 个图像保存到一个 pdf file.Also 理想情况下,我想在 pdf 文件的单个页面中保存 2 个图像。 SO 中有一些关于此的问题,但我找不到适合我的问题的解决方案。由于我有很多案例需要生成图像,所以我想将它们保存为单个 pdf 文件,因为这样更容易分析它们。如果有 suggestions/advice 帮助我,我将不胜感激。
这是示例文本文件 link 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)
Edit :正如您提到的,matplotlib 可能能够使用 PdfPages
function. See this related answer 自行处理所有事情。我原来的答案是 hack。
我认为您的代码中的错误是您每次执行循环时都在创建另一个 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)