Dynamically serving a matplotlib image to the web using python Dynamically serving a matplotlib image to the web using python python python

Dynamically serving a matplotlib image to the web using python


You should

  • first write to a cStringIO object
  • then write the HTTP header
  • then write the content of the cStringIO to stdout

Thus, if an error in savefig occured, you could still return something else, even another header. Some errors won't be recognized earlier, e.g., some problems with texts, too large image dimensions etc.

You need to tell savefig where to write the output. You can do:

format = "png"sio = cStringIO.StringIO()pyplot.savefig(sio, format=format)print "Content-Type: image/%s\n" % formatmsvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) # Needed this on windows, IISsys.stdout.write(sio.getvalue())

If you want to embed the image into HTML:

print "Content-Type: text/html\n"print """<html><body>...a bunch of text and html here...<img src="data:image/png;base64,%s"/>...more text and html...</body></html>""" % sio.getvalue().encode("base64").strip()


The above answers are a little outdated -- here's what works for me on Python3+ to get the raw bytes of the figure data.

import matplotlib.pyplot as pltfrom io import BytesIOfig = plt.figure()plt.plot(range(10))figdata = BytesIO()fig.savefig(figdata, format='png')

As mentioned in other answers you now need to set a 'Content-Type' header to 'image/png' and write out the bytes.

Depending on what you are using as your webserver the code may vary. I use Tornado as my webserver and the code to do that is:

self.set_header('Content-Type', 'image/png')self.write(figdata.getvalue())


what works for me with python3 is:

buf = io.BytesIO()plt.savefig(buf, format='png')image_base64 = base64.b64encode(buf.getvalue()).decode('utf-8').replace('\n', '')buf.close()