Skip to content

Commit 2b614cf

Browse files
committed
Merge pull request matplotlib#2453 from megies/pdfpages_keep_empty
PdfPages: add option to delete empty file when closed
2 parents 9f72865 + cb805ad commit 2b614cf

File tree

2 files changed

+84
-22
lines changed

2 files changed

+84
-22
lines changed

Diff for: lib/matplotlib/backends/backend_pdf.py

+48-22
Original file line numberDiff line numberDiff line change
@@ -2251,29 +2251,44 @@ class PdfPages(object):
22512251
"""
22522252
A multi-page PDF file.
22532253
2254-
Use like this::
2255-
2256-
# Initialize:
2257-
with PdfPages('foo.pdf') as pdf:
2258-
2259-
# As many times as you like, create a figure fig and save it:
2260-
# When no figure is specified the current figure is saved
2261-
pdf.savefig(fig)
2262-
pdf.savefig()
2263-
2264-
(In reality PdfPages is a thin wrapper around PdfFile, in order to
2265-
avoid confusion when using savefig and forgetting the format
2266-
argument.)
2254+
Examples
2255+
--------
2256+
2257+
>>> import matplotlib.pyplot as plt
2258+
>>> # Initialize:
2259+
>>> with PdfPages('foo.pdf') as pdf:
2260+
... # As many times as you like, create a figure fig and save it:
2261+
... fig = plt.figure()
2262+
... pdf.savefig(fig)
2263+
... # When no figure is specified the current figure is saved
2264+
... pdf.savefig()
2265+
2266+
Notes
2267+
-----
2268+
2269+
In reality :class:`PdfPages` is a thin wrapper around :class:`PdfFile`, in
2270+
order to avoid confusion when using :func:`~matplotlib.pyplot.savefig` and
2271+
forgetting the format argument.
22672272
"""
2268-
__slots__ = ('_file',)
2273+
__slots__ = ('_file', 'keep_empty')
22692274

2270-
def __init__(self, filename):
2275+
def __init__(self, filename, keep_empty=True):
22712276
"""
2272-
Create a new PdfPages object that will be written to the file
2273-
named *filename*. The file is opened at once and any older
2274-
file with the same name is overwritten.
2277+
Create a new PdfPages object.
2278+
2279+
Parameters
2280+
----------
2281+
2282+
filename: str
2283+
Plots using :meth:`PdfPages.savefig` will be written to a file at
2284+
this location. The file is opened at once and any older file with
2285+
the same name is overwritten.
2286+
keep_empty: bool, optional
2287+
If set to False, then empty pdf files will be deleted automatically
2288+
when closed.
22752289
"""
22762290
self._file = PdfFile(filename)
2291+
self.keep_empty = keep_empty
22772292

22782293
def __enter__(self):
22792294
return self
@@ -2287,6 +2302,8 @@ def close(self):
22872302
PDF file.
22882303
"""
22892304
self._file.close()
2305+
if self.get_pagecount() == 0 and self.keep_empty is False:
2306+
os.remove(self._file.fh.name)
22902307
self._file = None
22912308

22922309
def infodict(self):
@@ -2299,10 +2316,19 @@ def infodict(self):
22992316

23002317
def savefig(self, figure=None, **kwargs):
23012318
"""
2302-
Save the Figure instance *figure* to this file as a new page.
2303-
If *figure* is a number, the figure instance is looked up by
2304-
number, and if *figure* is None, the active figure is saved.
2305-
Any other keyword arguments are passed to Figure.savefig.
2319+
Saves a :class:`~matplotlib.figure.Figure` to this file as a new page.
2320+
2321+
Any other keyword arguments are passed to
2322+
:meth:`~matplotlib.figure.Figure.savefig`.
2323+
2324+
Parameters
2325+
----------
2326+
2327+
figure: :class:`~matplotlib.figure.Figure` or int, optional
2328+
Specifies what figure is saved to file. If not specified, the
2329+
active figure is saved. If a :class:`~matplotlib.figure.Figure`
2330+
instance is provided, this figure is saved. If an int is specified,
2331+
the figure instance to save is looked up by number.
23062332
"""
23072333
if isinstance(figure, Figure):
23082334
figure.savefig(self, format='pdf', **kwargs)

Diff for: lib/matplotlib/tests/test_backend_pdf.py

+36
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,39 @@ def test_multipage_pagecount():
5151
assert pdf.get_pagecount() == 1
5252
pdf.savefig()
5353
assert pdf.get_pagecount() == 2
54+
55+
56+
@cleanup
57+
def test_multipage_keep_empty():
58+
from matplotlib.backends.backend_pdf import PdfPages
59+
from tempfile import NamedTemporaryFile
60+
### test empty pdf files
61+
# test that an empty pdf is left behind with keep_empty=True (default)
62+
with NamedTemporaryFile(delete=False) as tmp:
63+
with PdfPages(tmp) as pdf:
64+
filename = pdf._file.fh.name
65+
assert os.path.exists(filename)
66+
os.remove(filename)
67+
# test if an empty pdf is deleting itself afterwards with keep_empty=False
68+
with NamedTemporaryFile(delete=False) as tmp:
69+
with PdfPages(tmp, keep_empty=False) as pdf:
70+
filename = pdf._file.fh.name
71+
assert not os.path.exists(filename)
72+
### test pdf files with content, they should never be deleted
73+
fig = plt.figure()
74+
ax = fig.add_subplot(111)
75+
ax.plot([1, 2, 3])
76+
# test that a non-empty pdf is left behind with keep_empty=True (default)
77+
with NamedTemporaryFile(delete=False) as tmp:
78+
with PdfPages(tmp) as pdf:
79+
filename = pdf._file.fh.name
80+
pdf.savefig()
81+
assert os.path.exists(filename)
82+
os.remove(filename)
83+
# test that a non-empty pdf is left behind with keep_empty=False
84+
with NamedTemporaryFile(delete=False) as tmp:
85+
with PdfPages(tmp, keep_empty=False) as pdf:
86+
filename = pdf._file.fh.name
87+
pdf.savefig()
88+
assert os.path.exists(filename)
89+
os.remove(filename)

0 commit comments

Comments
 (0)