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])
canv开发者_开发知识库as = 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!
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.
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
精彩评论