22

I would like to store the image generated by matplotlib in a variable raw_data to use it as inline image.

import os
import sys
os.environ['MPLCONFIGDIR'] = '/tmp/'
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt

print "Content-type: image/png\n"
plt.plot(range(10, 20))

raw_data = plt.show()

if raw_data:
    uri = 'data:image/png;base64,' + urllib.quote(base64.b64encode(raw_data))
    print '<img src = "%s"/>' % uri
else:
    print "No data"

#plt.savefig(sys.stdout, format='png')

None of the functions suit my use case:

  • plt.savefig(sys.stdout, format='png') - Writes it to stdout. This does help.. as I have to embed the image in a html file.
  • plt.show() / plt.draw() does nothing when executed from command line

2 Answers 2

33

Have you tried cStringIO or an equivalent?

import os
import sys
import matplotlib
import matplotlib.pyplot as plt
import StringIO
import urllib, base64

plt.plot(range(10, 20))
fig = plt.gcf()

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

print "Content-type: image/png\n"
uri = 'data:image/png;base64,' + urllib.quote(base64.b64encode(imgdata.buf))
print '<img src = "%s"/>' % uri
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks.. That helped... I was hoping there would be a way to directly get the image instead of using a file handle..
@Ramya: StringIO does not use filehandles. It is all in-memory storage and there is no OS limit to the number of StringIO instances: stackoverflow.com/questions/1177230/…
Don't forget to unquote the string before decoding, because I got some 'Incorrect padding' errors because of the url encoding.
FYI, in Python 3 you'll need to use io.BytesIO, eg: buf = io.BytesIO(); plt.gcf().savefig(buf, format='png'); buf.seek(0); return base64.b64encode(buf.read())
Instead of a plot, I have a 2d matrix. How do I return it as JPG image data as a variable? I was hoping imsave had a "return" kind of option.
23

Complete python 3 version, putting together Paul's answer and metaperture's comment.

import matplotlib.pyplot as plt
import io
import urllib, base64

plt.plot(range(10))
fig = plt.gcf()

buf = io.BytesIO()
fig.savefig(buf, format='png')
buf.seek(0)
string = base64.b64encode(buf.read())

uri = 'data:image/png;base64,' + urllib.parse.quote(string)
html = '<img src = "%s"/>' % uri

1 Comment

Hi, is there any way around the very long urls?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.