medgoode
medgoode

Reputation: 53

Determining if an image is closed after including in a ReportLab

I have written a Python script that will generate a series of graphs and then generate a PDF report that contains the graphs. The intention is that this will be generated on a server. I am using ReportLab to generate the PDF. The script is being run on a machine that is running Windows 7.

At the beginning of the script a list to store the ReportLab flowables and a list to store path of each figure is set.

Story = []
FigList = []

Each graph is generated using Matplotlib and saved as a PNG. The image is appended to Story and the path of the file is added to FigList.

fig = plt.figure(1)
ax = fig.add_subplot(1, 1, 1)
ax.plot(x, y)
fname = "figure.png"
fig.savefig(fname)
FigList.append(fname)
Story.append(Image(fname))

This is repeated for a number of images (approximately 10 - 15 in total). At the end of the script the document is built

doc = SimpleDocTemplate("report.pdf",
                        pagesize=A4,
                        rightMargin=cm,
                        leftMargin=cm,
                        topMargin=cm,
                        bottomMargin=cm)

doc.build(Story)

After this I wish to remove all the PNG files that have been created using

for f in FigList:
    if os.path.exists(f): os.remove(f)

However, I am presented with the following error

WindowsError: [Error 32] The process cannot access the file because it is being used by another process: 'image.png'

I am assuming here that the document creation process is being performed in a separate thread and so when the script attempts to remove the figure files they are still marked as open by the file manager.

It is important that these image files are deleted before the process finishes as this process may be executed many times, therefore the temporary image files will soon take up too much space.

Is there a way I can get the script to wait for all the images to be closed before proceeding to delete the files?

Upvotes: 0

Views: 1052

Answers (2)

medgoode
medgoode

Reputation: 53

It would seem that the problem can be solved by assigning Image(...) to a variable before appending it to Story and then deleting it afterwards. If we consider the example in the question, this modification becomes

fig = plt.figure(1)
ax = fig.add_subplot(1, 1, 1)
ax.plot(x, y)
fname = "figure.png"
fig.savefig(fname)
FigList.append(fname)
img = Image(fname)
Story.append(img)
del img

Note: This is not related to the file object created by savefig().

Upvotes: 3

notbad.jpeg
notbad.jpeg

Reputation: 3368

Have you tried wrapping your file open in a with statement? Usually python closes the file for you after leaving the with clause.

Edit: It looks like your fig.savefig(fname) might return the image file object. If that's correct, you could try calling close on each file object it returns after you're done.

Upvotes: 0

Related Questions