how to save a pylab figure into in-memory file which can be read into PIL image?
46,211
Solution 1
Remember to call buf.seek(0)
so Image.open(buf)
starts reading from the
beginning of the buf
:
import io
from PIL import Image
import matplotlib.pyplot as plt
plt.figure()
plt.plot([1, 2])
plt.title("test")
buf = io.BytesIO()
plt.savefig(buf, format='png')
buf.seek(0)
im = Image.open(buf)
im.show()
buf.close()
Solution 2
I like having it encapsulated in a function:
def fig2img(fig):
"""Convert a Matplotlib figure to a PIL Image and return it"""
import io
buf = io.BytesIO()
fig.savefig(buf)
buf.seek(0)
img = Image.open(buf)
return img
Then I can call it easily this way:
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
x = np.arange(-3,3)
plt.plot(x)
fig = plt.gcf()
img = fig2img(fig)
img.show()
Related videos on Youtube
Comments
-
nye17 almost 2 years
The following is my first shot which never works:
import cStringIO import pylab from PIL import Image pylab.figure() pylab.plot([1,2]) pylab.title("test") buffer = cStringIO.StringIO() pylab.savefig(buffer, format='png') im = Image.open(buffer.read()) buffer.close()
the error says,
Traceback (most recent call last): File "try.py", line 10, in <module> im = Image.open(buffer.read()) File "/awesomepath/python2.7/site-packages/PIL/Image.py", line 1952, in open fp = __builtin__.open(fp, "rb")
any ideas? I don't want the solution to involve extra packages.
-
nye17 over 12 yearsAwesome! it works like a charm! even when I substitute
io.BytesIO
with my originalStringIO
. Can you remind you what the why you choose to use the former here? Thanks! -
unutbu over 12 yearsFor Python2.6 or better, use
io.BytesIO
instead ofcStringIO.StringIO
for forward-compatibility. In Python3, thecStringIO
,StringIO
modules are gone. Their functionality is all in theio
module. -
Little Bobby Tables over 5 yearsHow do you set a sensible file name for your .png? It seems to just call mine
fig.png
- thanks. -
unutbu over 5 years@josh:
plt.savefig(buf, format='png')
writes to an in-memoryBytesIO
object. No file is created. The more usual way to usesavefig
is to callplt.savefig('/path/to/anyfilenameyouwant.png')
, which allows you to specify the filename. -
Little Bobby Tables over 5 yearsI am sending this in a response from a Falsk app so the file gets downloaded by Chrome, etc. Maybe there is a better way to do this, where I get to choose my file name (of the downloaded .png). Thanks though.
-
jmd_dk over 5 yearsIf you want the image as an array, you can get by without
PIL
/pillow
and useim = plt.imread(buf)
. You can also save theim
array usingplt.imsave('/path/to/saved/file.png', im)
.