I would like to add a figure generated with matplotlib to a reportlab canvas using the method drawImage and without having to save the figure to the hard drive first.
My question is related to: Is there a matplotlib flowable for ReportLab?, which was nicely solved. However, I do not wish to use DocTemplates, Stories, Flowables, etc. As said, I would like put it at a certain position in the canvas using drawImage.
I have tried to convert the matplotlib figure to a PIL image using the following methods:
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
For example, some code that fails to work is:
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()
Trying to draw imgdata
results in the error:
AttributeError: 'cStringIO.StringO' object has no attribute 'rfind'
While drawing im
gives:
AttributeError: rfind
Does somebody now how to solve this issue? Any help would be greatly appreciated.
Saving a plot on your disk as an image file Now if you want to save matplotlib figures as image files programmatically, then all you need is matplotlib. pyplot. savefig() function. Simply pass the desired filename (and even location) and the figure will be stored on your disk.
To save plot figure as JPG or PNG file, call savefig() function on matplotlib. pyplot object. Pass the file name along with extension, as string argument, to savefig() function.
The problem is that drawImage expects either an ImageReader object or a filepath, not a file handle.
The following should work:
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()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With