Advertisement
Guest User

Untitled

a guest
Jun 18th, 2019
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.89 KB | None | 0 0
  1. import os
  2. from matplotlib import pyplot as plt
  3. from matplotlib.backends.backend_pdf import PdfPages
  4. from reportlab.platypus import Paragraph, SimpleDocTemplate, Flowable
  5. from reportlab.lib.styles import getSampleStyleSheet
  6. from reportlab.pdfbase import pdfmetrics
  7. from reportlab.pdfgen import canvas
  8.  
  9. from pdfrw import PdfReader, PdfDict
  10. from pdfrw.buildxobj import pagexobj
  11. from pdfrw.toreportlab import makerl
  12.  
  13.  
  14. try:
  15. from cStringIO import StringIO as BytesIO
  16. except ImportError:
  17. from io import BytesIO
  18.  
  19. styles = getSampleStyleSheet()
  20. style = styles['Normal']
  21.  
  22. #Informações caso queiram rodar o código
  23. 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']
  24. mes = [0, 15, 149, 0, 59, 0, 0, 101, 45, 25, 751.07, 5358.3]
  25. acc = [0, 15, 164, 164, 223, 223, 223, 324, 369, 394, 1145.07, 6503.37]
  26.  
  27. class PdfImage(Flowable):
  28. """
  29. Generates a reportlab image flowable for matplotlib figures. It is initialized
  30. with either a matplotlib figure or a pointer to a list of pagexobj objects and
  31. an index for the pagexobj to be used.
  32. """
  33. def __init__(self, fig=None, width=200, height=200, cache=None, cacheindex=0):
  34. self.img_width = width
  35. self.img_height = height
  36. if fig is None and cache is None:
  37. raise ValueError("Either 'fig' or 'cache' must be provided")
  38. if fig is not None:
  39. imgdata = BytesIO()
  40. fig.savefig(imgdata, format='pdf')
  41. imgdata.seek(0)
  42. page, = PdfReader(imgdata).pages
  43. image = pagexobj(page)
  44. self.img_data = image
  45. else:
  46. self.img_data = None
  47. self.cache = cache
  48. self.cacheindex = cacheindex
  49.  
  50. def wrap(self, width, height):
  51. return self.img_width, self.img_height
  52.  
  53. def drawOn(self, canv, x, y, _sW=0):
  54. if _sW > 0 and hasattr(self, 'hAlign'):
  55. a = self.hAlign
  56. if a in ('CENTER', 'CENTRE', TA_CENTER):
  57. x += 0.5*_sW
  58. elif a in ('RIGHT', TA_RIGHT):
  59. x += _sW
  60. elif a not in ('LEFT', TA_LEFT):
  61. raise ValueError("Bad hAlign value " + str(a))
  62. canv.saveState()
  63. if self.img_data is not None:
  64. img = self.img_data
  65. else:
  66. img = self.cache[self.cacheindex]
  67. if isinstance(img, PdfDict):
  68. xscale = self.img_width / img.BBox[2]
  69. yscale = self.img_height / img.BBox[3]
  70. canv.translate(x, y)
  71. canv.scale(xscale, yscale)
  72. canv.doForm(makerl(canv, img))
  73. else:
  74. canv.drawImage(img, x, y, self.img_width, self.img_height)
  75. canv.restoreState()
  76.  
  77.  
  78. class PdfImageCache(object):
  79. """
  80. Saves matplotlib figures to a temporary multi-page PDF file using the 'savefig'
  81. method. When closed the images are extracted and saved to the attribute 'cache'.
  82. The temporary PDF file is then deleted. The 'savefig' returns a PdfImage object
  83. with a pointer to the 'cache' list and an index for the figure. Use of this
  84. cache reduces duplicated resources in the reportlab generated PDF file.
  85.  
  86. Use is similar to matplotlib's PdfPages object. When not used as a context
  87. manager, the 'close()' method must be explictly called before the reportlab
  88. document is built.
  89. """
  90. def __init__(self):
  91. self.pdftempfile = '_temporary_pdf_image_cache_.pdf'
  92. self.pdf = PdfPages(self.pdftempfile)
  93. self.cache = []
  94. self.count = 0
  95.  
  96. def __enter__(self):
  97. return self
  98.  
  99. def __exit__(self, *args):
  100. self.close()
  101.  
  102. def close(self, *args):
  103. self.pdf.close()
  104. pages = PdfReader(self.pdftempfile).pages
  105. pages = [pagexobj(x) for x in pages]
  106. self.cache.extend(pages)
  107. os.remove(self.pdftempfile)
  108.  
  109. def savefig(self, fig, width=200, height=200):
  110. self.pdf.savefig(fig)
  111. index = self.count
  112. self.count += 1
  113. return PdfImage(width=width, height=height, cache=self.cache, cacheindex=index)
  114.  
  115.  
  116.  
  117. def make_report_cached_figs(outfn):
  118. """
  119. Makes a dummy report with nfig matplotlib plots using PdfImageCache
  120. to reduce PDF file size.
  121. """
  122.  
  123. doc = SimpleDocTemplate(outfn)
  124. style = styles["Normal"]
  125. story = []
  126.  
  127. with PdfImageCache() as pdfcache:
  128.  
  129. fig = plt.figure(figsize=(5, 5))
  130. plt.bar(div, acc, width = 0.8, color = 'silver', label = 'Year')
  131. plt.bar(div, mes, width = 0.4, color = 'k', label = 'Month', alpha = 0.5)
  132. plt.legend()
  133. plt.xticks(rotation=60)
  134. plt.close()
  135. img0 = pdfcache.savefig(fig, width=185, height=135)
  136. img0.drawOn(doc, 0, 100)
  137.  
  138. story.append(img0)
  139.  
  140. doc.build(story)
  141.  
  142. make_report_cached_figs("Test.pdf")
  143.  
  144. AttributeError: 'SimpleDocTemplate' object has no attribute 'saveState'
  145.  
  146. img = self.cache[self.cacheindex]
  147. IndexError: list index out of range
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement