Skip to content

Commit 7f1a1e6

Browse files
committed
Create a PdfFile wrapper named PdfPages to act as the target of savefig
to avoid saving figures in png format onto the file-like PdfPages object. svn path=/trunk/matplotlib/; revision=6739
1 parent 508d780 commit 7f1a1e6

File tree

4 files changed

+79
-11
lines changed

4 files changed

+79
-11
lines changed

CHANGELOG

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
2009-01-06 Change user-visible multipage pdf object to PdfPages to
2+
avoid accidents with the file-like PdfFile. - JKS
3+
14
2009-01-05 Fix a bug in pdf usetex: allow using non-embedded fonts. - JKS
25

36
2009-01-05 optional use of preview.sty in usetex mode. - JJL

doc/api/api_changes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ This chapter is a log of changes to matplotlib that affect the
66
outward-facing API. If updating matplotlib breaks your scripts, this
77
list may help describe what changes may be necessary in your code.
88

9+
* You can now print several figures to one pdf file. See the docstrings
10+
of the class :class:`matplotlib.backends.backend_pdf.PdfPages` for
11+
more information.
12+
913
* Removed configobj_ and `enthought.traits`_ packages, which are only
1014
required by the experimental traited config and are somewhat out of
1115
date. If needed, install them independently.
Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,33 @@
1+
# This is a demo of creating a pdf file with several pages.
2+
13
import numpy as np
24
import matplotlib
3-
from matplotlib.backends.backend_pdf import PdfFile
5+
from matplotlib.backends.backend_pdf import PdfPages
46
from pylab import *
57

6-
pdf = PdfFile('multipage_pdf.pdf')
8+
# Create the PdfPages object to which we will save the pages:
9+
pdf = PdfPages('multipage_pdf.pdf')
710

811
figure(figsize=(3,3))
912
plot(range(7), [3,1,4,1,5,9,2], 'r-o')
1013
title('Page One')
11-
savefig(pdf, format='pdf')
14+
savefig(pdf, format='pdf') # note the format='pdf' argument!
1215
close()
1316

1417
rc('text', usetex=True)
1518
figure(figsize=(8,6))
1619
x = np.arange(0,5,0.1)
1720
plot(x, np.sin(x), 'b-')
1821
title('Page Two')
19-
savefig(pdf, format='pdf')
22+
pdf.savefig() # here's another way - or you could do pdf.savefig(1)
2023
close()
2124

2225
rc('text', usetex=False)
23-
figure(figsize=(4,5))
26+
fig=figure(figsize=(4,5))
2427
plot(x, x*x, 'ko')
2528
title('Page Three')
26-
savefig(pdf, format='pdf')
29+
pdf.savefig(fig) # or you can pass a Figure object to pdf.savefig
2730
close()
2831

32+
# Remember to close the object - otherwise the file will not be usable
2933
pdf.close()

lib/matplotlib/backends/backend_pdf.py

Lines changed: 62 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1882,6 +1882,63 @@ def new_figure_manager(num, *args, **kwargs):
18821882
manager = FigureManagerPdf(canvas, num)
18831883
return manager
18841884

1885+
class PdfPages(object):
1886+
"""
1887+
A multi-page PDF file.
1888+
1889+
Use like this:
1890+
1891+
# Initialize:
1892+
pdf_pages = PdfPages('foo.pdf')
1893+
1894+
# As many times as you like, create a figure fig, then either:
1895+
fig.savefig(pdf_pages, format='pdf') # note the format argument!
1896+
# or:
1897+
pdf_pages.savefig(fig)
1898+
1899+
# Once you are done, remember to close the object:
1900+
pdf_pages.close()
1901+
1902+
(In reality PdfPages is a thin wrapper around PdfFile, in order to
1903+
avoid confusion when using savefig and forgetting the format
1904+
argument.)
1905+
"""
1906+
__slots__ = ('_file',)
1907+
1908+
def __init__(self, filename):
1909+
"""
1910+
Create a new PdfPages object that will be written to the file
1911+
named *filename*. The file is opened at once and any older
1912+
file with the same name is overwritten.
1913+
"""
1914+
self._file = PdfFile(filename)
1915+
1916+
def close(self):
1917+
"""
1918+
Finalize this object, making the underlying file a complete
1919+
PDF file.
1920+
"""
1921+
self._file.close()
1922+
self._file = None
1923+
1924+
def savefig(self, figure=None, **kwargs):
1925+
"""
1926+
Save the Figure instance *figure* to this file as a new page.
1927+
If *figure* is a number, the figure instance is looked up by
1928+
number, and if *figure* is None, the active figure is saved.
1929+
Any other keyword arguments are passed to Figure.savefig.
1930+
"""
1931+
if isinstance(figure, Figure):
1932+
figure.savefig(self, format='pdf', **kwargs)
1933+
else:
1934+
if figure is None:
1935+
figureManager = Gcf.get_active()
1936+
else:
1937+
figureManager = Gcf.get_fig_manager(figure)
1938+
if figureManager is None:
1939+
raise ValueError, "No such figure: " + `figure`
1940+
else:
1941+
figureManager.canvas.figure.savefig(self, format='pdf')
18851942

18861943
class FigureCanvasPdf(FigureCanvasBase):
18871944
"""
@@ -1905,19 +1962,19 @@ def print_pdf(self, filename, **kwargs):
19051962
image_dpi = kwargs.get('dpi', 72) # dpi to use for images
19061963
self.figure.set_dpi(72) # there are 72 pdf points to an inch
19071964
width, height = self.figure.get_size_inches()
1908-
if isinstance(filename, PdfFile):
1909-
file = filename
1965+
if isinstance(filename, PdfPages):
1966+
file = filename._file
19101967
else:
19111968
file = PdfFile(filename)
19121969
file.newPage(width, height)
19131970
renderer = MixedModeRenderer(
19141971
width, height, 72, RendererPdf(file, image_dpi))
19151972
self.figure.draw(renderer)
19161973
renderer.finalize()
1917-
if file != filename: # we opened the file
1918-
file.close()
1919-
else: # multipage file; just finish off the page
1974+
if isinstance(filename, PdfPages): # finish off this page
19201975
file.endStream()
1976+
else: # we opened the file above; now finish it off
1977+
file.close()
19211978

19221979
class FigureManagerPdf(FigureManagerBase):
19231980
pass

0 commit comments

Comments
 (0)