2010-08-10 3 views
8

Я сохранил некоторые графики из matplotlib в формате pdf, потому что он, кажется, предлагает лучшее качество. Как включить PDF-образ в PDF-документ с помощью ReportLab? Метод удобства Image (путь к файлу) не работает для этого формата.PDF-изображение в PDF-документе с использованием ReportLab (Python)

спасибо.

ответ

-3

Использование из reportlab.graphics импорта renderPDF

+3

Это неправильно. renderPDF берет документ EXISTING и создает PDF-файл. Точная противоположность тому, что хочет плакат. –

2

По ReportLab's FAQ это возможно только с ReportLab PLUS:

Могу ли я использовать векторную графику в своих PDF-файлов?

Нет, пакет с открытым исходным кодом не делает . PageCatcher (смотрите предыдущий ответ) позволяет легко включать любое векторное изображение, сохраняя его как PDF, а затем использовать его точно , как если бы файл изображения, а также отчет Markup Language принимает PDF файлы вместе с JPG, GIF и PNG.

Update: Я не смотрел на это некоторое время, но on the page of pdfrw он говорит:

pdfrw может читать и записывать файлы в формате PDF, а также может быть использован для чтения PDF-файлов в который может затем использоваться внутри reportlab.

+0

Это правильно. Есть несколько примеров использования pdfrw для этого как на странице pdfrw, так и в некоторых [вопросах] (http://stackoverflow.com/questions/31712386/loading-matplotlib-object-into-reportlab/) здесь –

1

Вы можете использовать замечательный пакет pdfrw вместе с ReportLab и использовать его для передачи файлов, как объектов Matplotlib фигур непосредственно в текучий:

Это ответил раньше, но я хочу, чтобы дать минимальный пример здесь, пожалуйста, смотрите здесь: https://stackoverflow.com/a/13870512/4497962

from io import BytesIO 
import matplotlib.pyplot as plt 
from pdfrw import PdfReader, PdfDict 
from pdfrw.buildxobj import pagexobj 
from pdfrw.toreportlab import makerl 
from reportlab.platypus import Flowable 
from reportlab.lib.enums import TA_JUSTIFY,TA_LEFT,TA_CENTER,TA_RIGHT 

class PdfImage(Flowable): 
    """ 
    PdfImage wraps the first page from a PDF file as a Flowable 
    which can be included into a ReportLab Platypus document. 
    Based on the vectorpdf extension in rst2pdf (http://code.google.com/p/rst2pdf/) 

    This can be used from the place where you want to return your matplotlib image 
    as a Flowable: 

     img = BytesIO() 

     fig, ax = plt.subplots(figsize=(canvaswidth,canvaswidth)) 

     ax.plot([1,2,3],[6,5,4],antialiased=True,linewidth=2,color='red',label='a curve') 

     fig.savefig(img,format='PDF') 

     return(PdfImage(img)) 

    """ 

    def __init__(self, filename_or_object, width=None, height=None, kind='direct'): 
     # If using StringIO buffer, set pointer to begining 
     if hasattr(filename_or_object, 'read'): 
      filename_or_object.seek(0) 
      #print("read") 
     self.page = PdfReader(filename_or_object, decompress=False).pages[0] 
     self.xobj = pagexobj(self.page) 

     self.imageWidth = width 
     self.imageHeight = height 
     x1, y1, x2, y2 = self.xobj.BBox 

     self._w, self._h = x2 - x1, y2 - y1 
     if not self.imageWidth: 
      self.imageWidth = self._w 
     if not self.imageHeight: 
      self.imageHeight = self._h 
     self.__ratio = float(self.imageWidth)/self.imageHeight 
     if kind in ['direct','absolute'] or width==None or height==None: 
      self.drawWidth = width or self.imageWidth 
      self.drawHeight = height or self.imageHeight 
     elif kind in ['bound','proportional']: 
      factor = min(float(width)/self._w,float(height)/self._h) 
      self.drawWidth = self._w*factor 
      self.drawHeight = self._h*factor 

    def wrap(self, availableWidth, availableHeight): 
     """ 
     returns draw- width and height 

     convenience function to adapt your image 
     to the available Space that is available 
     """ 
     return self.drawWidth, self.drawHeight 

    def drawOn(self, canv, x, y, _sW=0): 
     """ 
     translates Bounding Box and scales the given canvas 
     """ 
     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)) 

     #xobj_name = makerl(canv._doc, self.xobj) 
     xobj_name = makerl(canv, self.xobj) 

     xscale = self.drawWidth/self._w 
     yscale = self.drawHeight/self._h 

     x -= self.xobj.BBox[0] * xscale 
     y -= self.xobj.BBox[1] * yscale 

     canv.saveState() 
     canv.translate(x, y) 
     canv.scale(xscale, yscale) 
     canv.doForm(xobj_name) 
     canv.restoreState() 
+0

Это именно то, что мне нужно! Большое спасибо за код! – desa

+0

Если вам понравилось это, вы также можете взглянуть на это: https://pypi.python.org/pypi/autobasedoc/ – skidzo

1

Вы можете использовать SVG экспорта из Matplotlib и использовать библиотеку svglib питона включить векторную графику в ReportLab генерироваться PDF файлов. svglib принимает файл svg и создает объект чертежа, который может быть непосредственно использован в reportlab.

Смотрите также этот вопрос для более подробной информации: Generating PDFs from SVG input

Смежные вопросы