在网页上绘制matplotlib图形

12 投票
2 回答
16292 浏览
提问于 2025-04-16 14:53

下面的代码当然会创建一个名为 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)

注意:如果这些图像是用相同的参数频繁生成的,你可能想要添加缓存功能。比如,可以根据参数构建一个键,把图像数据写入缓存中,然后在重新生成图形之前先检查缓存。

撰写回答