Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import os
- from matplotlib import pyplot as plt
- from matplotlib.backends.backend_pdf import PdfPages
- from reportlab.platypus import Paragraph, SimpleDocTemplate, Flowable
- from reportlab.lib.styles import getSampleStyleSheet
- from reportlab.pdfbase import pdfmetrics
- from reportlab.pdfgen import canvas
- from pdfrw import PdfReader, PdfDict
- from pdfrw.buildxobj import pagexobj
- from pdfrw.toreportlab import makerl
- try:
- from cStringIO import StringIO as BytesIO
- except ImportError:
- from io import BytesIO
- styles = getSampleStyleSheet()
- style = styles['Normal']
- #Informações caso queiram rodar o código
- div = ['may/18', 'jun/18', 'jul/18', 'aug/18', 'sep/18', 'oct/18', 'nov/18', 'dec/18', 'jan/19', 'feb/19', 'mar/19', 'apr/19']
- mes = [0, 15, 149, 0, 59, 0, 0, 101, 45, 25, 751.07, 5358.3]
- acc = [0, 15, 164, 164, 223, 223, 223, 324, 369, 394, 1145.07, 6503.37]
- class PdfImage(Flowable):
- """
- Generates a reportlab image flowable for matplotlib figures. It is initialized
- with either a matplotlib figure or a pointer to a list of pagexobj objects and
- an index for the pagexobj to be used.
- """
- def __init__(self, fig=None, width=200, height=200, cache=None, cacheindex=0):
- self.img_width = width
- self.img_height = height
- if fig is None and cache is None:
- raise ValueError("Either 'fig' or 'cache' must be provided")
- if fig is not None:
- imgdata = BytesIO()
- fig.savefig(imgdata, format='pdf')
- imgdata.seek(0)
- page, = PdfReader(imgdata).pages
- image = pagexobj(page)
- self.img_data = image
- else:
- self.img_data = None
- self.cache = cache
- self.cacheindex = cacheindex
- def wrap(self, width, height):
- return self.img_width, self.img_height
- def drawOn(self, canv, x, y, _sW=0):
- if _sW > 0 and hasattr(self, 'hAlign'):
- a = self.hAlign
- if a in ('CENTER', 'CENTRE', TA_CENTER):
- x += 0.5*_sW
- elif a in ('RIGHT', TA_RIGHT):
- x += _sW
- elif a not in ('LEFT', TA_LEFT):
- raise ValueError("Bad hAlign value " + str(a))
- canv.saveState()
- if self.img_data is not None:
- img = self.img_data
- else:
- img = self.cache[self.cacheindex]
- if isinstance(img, PdfDict):
- xscale = self.img_width / img.BBox[2]
- yscale = self.img_height / img.BBox[3]
- canv.translate(x, y)
- canv.scale(xscale, yscale)
- canv.doForm(makerl(canv, img))
- else:
- canv.drawImage(img, x, y, self.img_width, self.img_height)
- canv.restoreState()
- class PdfImageCache(object):
- """
- Saves matplotlib figures to a temporary multi-page PDF file using the 'savefig'
- method. When closed the images are extracted and saved to the attribute 'cache'.
- The temporary PDF file is then deleted. The 'savefig' returns a PdfImage object
- with a pointer to the 'cache' list and an index for the figure. Use of this
- cache reduces duplicated resources in the reportlab generated PDF file.
- Use is similar to matplotlib's PdfPages object. When not used as a context
- manager, the 'close()' method must be explictly called before the reportlab
- document is built.
- """
- def __init__(self):
- self.pdftempfile = '_temporary_pdf_image_cache_.pdf'
- self.pdf = PdfPages(self.pdftempfile)
- self.cache = []
- self.count = 0
- def __enter__(self):
- return self
- def __exit__(self, *args):
- self.close()
- def close(self, *args):
- self.pdf.close()
- pages = PdfReader(self.pdftempfile).pages
- pages = [pagexobj(x) for x in pages]
- self.cache.extend(pages)
- os.remove(self.pdftempfile)
- def savefig(self, fig, width=200, height=200):
- self.pdf.savefig(fig)
- index = self.count
- self.count += 1
- return PdfImage(width=width, height=height, cache=self.cache, cacheindex=index)
- def make_report_cached_figs(outfn):
- """
- Makes a dummy report with nfig matplotlib plots using PdfImageCache
- to reduce PDF file size.
- """
- doc = SimpleDocTemplate(outfn)
- style = styles["Normal"]
- story = []
- with PdfImageCache() as pdfcache:
- fig = plt.figure(figsize=(5, 5))
- plt.bar(div, acc, width = 0.8, color = 'silver', label = 'Year')
- plt.bar(div, mes, width = 0.4, color = 'k', label = 'Month', alpha = 0.5)
- plt.legend()
- plt.xticks(rotation=60)
- plt.close()
- img0 = pdfcache.savefig(fig, width=185, height=135)
- img0.drawOn(doc, 0, 100)
- story.append(img0)
- doc.build(story)
- make_report_cached_figs("Test.pdf")
- AttributeError: 'SimpleDocTemplate' object has no attribute 'saveState'
- img = self.cache[self.cacheindex]
- IndexError: list index out of range
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement