From 9f778851d3280cc359cab4ebb9bf6dabab9b82bf Mon Sep 17 00:00:00 2001 From: Ulrich Dobramysl Date: Mon, 12 Jan 2015 20:18:17 +0000 Subject: [PATCH 1/4] Add per-page pdf notes in PdfFile and PdfPages. --- lib/matplotlib/backends/backend_pdf.py | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/lib/matplotlib/backends/backend_pdf.py b/lib/matplotlib/backends/backend_pdf.py index 085c0e7ec665..2963f59b70d9 100644 --- a/lib/matplotlib/backends/backend_pdf.py +++ b/lib/matplotlib/backends/backend_pdf.py @@ -480,6 +480,9 @@ def __init__(self, filename): self.paths = [] + self.pageAnnotations = [] # A list of annotations for the + # current page + # The PDF spec recommends to include every procset procsets = [Name(x) for x in "PDF Text ImageB ImageC ImageI".split()] @@ -507,7 +510,8 @@ def newPage(self, width, height): 'Contents': contentObject, 'Group': {'Type': Name('Group'), 'S': Name('Transparency'), - 'CS': Name('DeviceRGB')} + 'CS': Name('DeviceRGB')}, + 'Annots': self.pageAnnotations, } pageObject = self.reserveObject('page') self.writeObject(pageObject, thePage) @@ -519,6 +523,20 @@ def newPage(self, width, height): # graphics context: currently only the join style needs to be set self.output(GraphicsContextPdf.joinstyles['round'], Op.setlinejoin) + # Clear the list of annotations for the next page + self.pageAnnotations = [] + + def newTextnote(self, text, positionRect = [-100, -100, 0, 0]): + # Create a new annotation of type text + theNote = {'Type': Name('Annot'), + 'Subtype': Name('Text'), + 'Contents': text, + 'Rect': positionRect, + } + annotObject = self.reserveObject('annotation') + self.writeObject(annotObject, theNote) + self.pageAnnotations.append(annotObject) + def close(self): self.endStream() # Write out the various deferred objects @@ -2445,6 +2463,11 @@ def get_pagecount(self): """ return len(self._file.pageList) + def attach_note(self, text): + """ + Add a new text note to the page to be saved next. + """ + self._file.newTextnote(text) class FigureCanvasPdf(FigureCanvasBase): """ From 4fa8a0adbb1c64035cd8d1aee1e6dfa14628796d Mon Sep 17 00:00:00 2001 From: Ulrich Dobramysl Date: Tue, 13 Jan 2015 07:26:41 +0000 Subject: [PATCH 2/4] Correct PEP8 violations. --- lib/matplotlib/backends/backend_pdf.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/matplotlib/backends/backend_pdf.py b/lib/matplotlib/backends/backend_pdf.py index 2963f59b70d9..de522acbdbc5 100644 --- a/lib/matplotlib/backends/backend_pdf.py +++ b/lib/matplotlib/backends/backend_pdf.py @@ -480,8 +480,8 @@ def __init__(self, filename): self.paths = [] - self.pageAnnotations = [] # A list of annotations for the - # current page + self.pageAnnotations = [] # A list of annotations for the + # current page # The PDF spec recommends to include every procset procsets = [Name(x) @@ -526,7 +526,7 @@ def newPage(self, width, height): # Clear the list of annotations for the next page self.pageAnnotations = [] - def newTextnote(self, text, positionRect = [-100, -100, 0, 0]): + def newTextnote(self, text, positionRect=[-100, -100, 0, 0]): # Create a new annotation of type text theNote = {'Type': Name('Annot'), 'Subtype': Name('Text'), @@ -2469,6 +2469,7 @@ def attach_note(self, text): """ self._file.newTextnote(text) + class FigureCanvasPdf(FigureCanvasBase): """ The canvas the figure renders into. Calls the draw and print fig From fc52db635f572774666d93728a53224df5dc6f58 Mon Sep 17 00:00:00 2001 From: Ulrich Dobramysl Date: Tue, 13 Jan 2015 07:44:48 +0000 Subject: [PATCH 3/4] Add optional positionRect argument to the PdfPages.attach_note method to be able to specify the new note's position. --- lib/matplotlib/backends/backend_pdf.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/matplotlib/backends/backend_pdf.py b/lib/matplotlib/backends/backend_pdf.py index de522acbdbc5..7e26871789cd 100644 --- a/lib/matplotlib/backends/backend_pdf.py +++ b/lib/matplotlib/backends/backend_pdf.py @@ -2463,11 +2463,14 @@ def get_pagecount(self): """ return len(self._file.pageList) - def attach_note(self, text): + def attach_note(self, text, positionRect=[-100, -100, 0, 0]): """ - Add a new text note to the page to be saved next. + Add a new text note to the page to be saved next. The optional + positionRect specifies the position of the new note on the + page. It is outside the page per default to make sure it is + invisible on printouts. """ - self._file.newTextnote(text) + self._file.newTextnote(text, positionRect) class FigureCanvasPdf(FigureCanvasBase): From f65281a3d1ef9ea63d60a9cb6f0712766b383ad0 Mon Sep 17 00:00:00 2001 From: Ulrich Dobramysl Date: Tue, 13 Jan 2015 07:46:04 +0000 Subject: [PATCH 4/4] Include a pdf note in the multipage_pdf.py example. Document the PdfPages.attach_note method in the whats_new section. --- doc/users/whats_new/pdfpages_notes.rst | 12 ++++++++++++ examples/pylab_examples/multipage_pdf.py | 2 ++ 2 files changed, 14 insertions(+) create mode 100644 doc/users/whats_new/pdfpages_notes.rst diff --git a/doc/users/whats_new/pdfpages_notes.rst b/doc/users/whats_new/pdfpages_notes.rst new file mode 100644 index 000000000000..9f4784ff76e8 --- /dev/null +++ b/doc/users/whats_new/pdfpages_notes.rst @@ -0,0 +1,12 @@ +Per-page pdf notes in multi-page pdfs (PdfPages) +------------------------------------------------ + +Add a new method attach_note to the PdfPages class, allowing the +attachment of simple text notes to pages in a multi-page pdf of +figures. The new note is visible in the list of pdf annotations in a +viewer that has this facility (Adobe Reader, OSX Preview, Skim, +etc.). Per default the note itself is kept off-page to prevent it to +appear in print-outs. + +PdfPages.attach_note needs to be called before savefig in order to be +added to the correct figure. diff --git a/examples/pylab_examples/multipage_pdf.py b/examples/pylab_examples/multipage_pdf.py index 2ccdfd2fe046..c639b62726c0 100644 --- a/examples/pylab_examples/multipage_pdf.py +++ b/examples/pylab_examples/multipage_pdf.py @@ -20,6 +20,8 @@ x = np.arange(0, 5, 0.1) plt.plot(x, np.sin(x), 'b-') plt.title('Page Two') + pdf.attach_note("plot of sin(x)") # you can add a pdf note to + # attach metadata to a page pdf.savefig() plt.close()