如何在reportlab画布中绘制matplotlib图形?

问题描述 投票:0回答:2

我想使用方法drawImage将用matplotlib生成的图形添加到reportlab画布中,而不必先将图形保存到硬盘驱动器。

我的问题与: 有一个用于ReportLab的matplotlib flowable吗?,这个问题很好解决了。 但是,我不想使用 DocTemplates、Stories、Flowables 等。如上所述,我想使用 drawImage 将其放在画布中的某个位置。

我尝试使用以下方法将 matplotlib 图转换为 PIL 图像:

1)http://www.icare.univ-lille1.fr/wiki/index.php/How_to_convert_a_matplotlib_figure_to_a_numpy_array_or_a_PIL_image

2)http://matplotlib.org/faq/howto_faq.html#matplotlib-in-a-web-application-server

例如,一些无法工作的代码是:

import Image
import matplotlib.pyplot as plt
import cStringIO
from reportlab.pdfgen import canvas
from reportlab.lib.units import inch, cm

fig = plt.figure(figsize=(4, 3))
plt.plot([1,2,3,4])
plt.ylabel('some numbers')

imgdata = cStringIO.StringIO()
fig.savefig(imgdata, format='png')
imgdata.seek(0)  # rewind the data
im = Image.open(imgdata)

c = canvas.Canvas('test.pdf')
#c.drawImage(imgdata, cm, cm, inch, inch)
c.drawImage(im, cm, cm, inch, inch)
c.save()

尝试绘制

imgdata
会导致错误:

AttributeError: 'cStringIO.StringO' object has no attribute 'rfind'

绘图时

im
给出:

AttributeError: rfind

现在有人如何解决这个问题吗? 任何帮助将不胜感激。

python matplotlib reportlab
2个回答
14
投票

问题在于,drawImage 需要 ImageReader 对象或文件路径,而不是文件句柄。

以下应该有效:

from PIL import Image
import matplotlib.pyplot as plt
import cStringIO
from reportlab.pdfgen import canvas
from reportlab.lib.units import inch, cm

from reportlab.lib.utils import ImageReader

fig = plt.figure(figsize=(4, 3))
plt.plot([1,2,3,4])
plt.ylabel('some numbers')

imgdata = cStringIO.StringIO()
fig.savefig(imgdata, format='png')
imgdata.seek(0)  # rewind the data

Image = ImageReader(imgdata)

c = canvas.Canvas('test.pdf')
c.drawImage(Image, cm, cm, inch, inch)
c.save()

12
投票

Python 3 的解决方案,并将 matplotlib 图嵌入为矢量图像(无光栅化)。因为我搜索了很长时间才在这里重新发布。

import matplotlib.pyplot as plt
from io import BytesIO
from reportlab.pdfgen import canvas
from reportlab.graphics import renderPDF
from svglib.svglib import svg2rlg

fig = plt.figure(figsize=(4, 3))
plt.plot([1,2,3,4])
plt.ylabel('some numbers')

imgdata = BytesIO()
fig.savefig(imgdata, format='svg')
imgdata.seek(0)  # rewind the data

drawing=svg2rlg(imgdata)

c = canvas.Canvas('test2.pdf')
renderPDF.draw(drawing,c, 10, 40)
c.drawString(10, 300, "So nice it works")
c.showPage()
c.save()

svglib 可从 conda-forge 获得。

© www.soinside.com 2019 - 2024. All rights reserved.