Plot matplotlib on the Web
Solution 1
First you need a page to load a url from the webserver controller which generates the image:
<img src="/matplot/makegraph?arg1=foo" />
Then, embed the matplotlib code into the makegraph
controller. You just need to capture the canvas rendered PNG in a memory buffer, then create an HTTP response and write the bytes back to the browser:
import cStringIO
from matplotlib.figure import Figure
from matplotlib.backends.backend_agg import FigureCanvasAgg
fig = Figure(figsize=[4,4])
ax = fig.add_axes([.1,.1,.8,.8])
ax.scatter([1,2], [3,4])
canvas = FigureCanvasAgg(fig)
# write image data to a string buffer and get the PNG image bytes
buf = cStringIO.StringIO()
canvas.print_png(buf)
data = buf.getvalue()
# pseudo-code for generating the http response from your
# webserver, and writing the bytes back to the browser.
# replace this with corresponding code for your web framework
headers = {
'Content-Type': 'image/png',
'Content-Length': len(data)
}
response.write(200, 'OK', headers, data)
Note: you may want to add caching for these if they're frequently generated with the same arguments, e.g. construct a key from the args and write the image data to memcache, then check memcache before regenerating the graph.
Solution 2
Just to update for python3
The StringIO and cStringIO modules are gone. Instead, import the io module and use io.StringIO https://docs.python.org/3.5/whatsnew/3.0.html?highlight=cstringio
So now would be something like:
import io
from matplotlib.figure import Figure
from matplotlib import pyplot as plt
fig = Figure(figsize=[4,4])
ax = fig.add_axes([.1,.1,.8,.8])
ax.scatter([1,2], [3,4])
buf = io.BytesIO()
fig.savefig(buf, format='png')
plt.close(fig)
data=buf.getvalue()
# In my case I would have used Django for the webpage
response = HttpResponse(data, content_type='image/png')
return response
Related videos on Youtube
Jason Strimpel
Passionate technologist and experienced leader. My super power is found at the intersection of engineering, sales and leadership.
Updated on November 11, 2020Comments
-
Jason Strimpel over 3 years
The following code will of course create a PNG named test and save it on the server:
from matplotlib.figure import Figure from matplotlib.backends.backend_agg import FigureCanvasAgg fig = Figure(figsize=[4,4]) ax = fig.add_axes([.1,.1,.8,.8]) ax.scatter([1,2], [3,4]) canvas = FigureCanvasAgg(fig) canvas.print_figure("test.png")
Then to view the image in the browser, we have to go to example.com/test.png. This means we have to call the page with the Python code first to create the test.png file, then go to the PNG file. Is there a way to draw the PNG and output from the Python page that creates the image? Thanks!
-
umbreonben over 11 yearsIt appears you can also do plt.savefig(buf,format="png",facecolor="white") or fig.savefig(). So you dont have to deal with the canvas object.