在网页上绘制matplotlib图形
下面的代码当然会创建一个名为 test 的 PNG 图片,并把它保存在服务器上:
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")
然后,要在浏览器中查看这个图片,我们需要访问 example.com/test.png。这意味着我们必须先运行包含 Python 代码的页面来生成 test.png 文件,然后再去查看这个 PNG 文件。请问有没有办法直接在生成图片的 Python 页面上显示这个 PNG 图片呢?谢谢!
2 个回答
6
这里是关于Python 3的一些更新
之前的StringIO和cStringIO模块已经不再使用了。现在你需要导入io模块,然后使用io.StringIO。
你可以查看这个链接了解更多信息:https://docs.python.org/3.5/whatsnew/3.0.html?highlight=cstringio
所以现在的写法大概是这样的:
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
24
首先,你需要一个页面来加载来自网络服务器控制器的 URL,这个控制器会生成图像:
<img src="/matplot/makegraph?arg1=foo" />
接下来,把 matplotlib 的代码嵌入到 makegraph
控制器中。你只需要把生成的 PNG 图像保存在内存缓冲区中,然后创建一个 HTTP 响应,把这些字节写回到浏览器里:
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)
注意:如果这些图像是用相同的参数频繁生成的,你可能想要添加缓存功能。比如,可以根据参数构建一个键,把图像数据写入缓存中,然后在重新生成图形之前先检查缓存。