You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django Web应用中Matplotlib多请求绘图重叠问题求助

解决Django中Matplotlib多请求图表重叠问题

这个问题我之前做项目时也踩过坑!根源在于你用的是Matplotlib的全局pyplot接口(就是plt.xxx这类函数),在Django这种多请求并发的Web环境里,不同请求会共享这个全局状态——前一次绘图的残留元素(比如线条、数据点)没被彻底清理,就会和新请求的内容叠加在一起,导致图表混乱。

给你两个靠谱的解决方案,优先选第一个:

方案1:使用Matplotlib面向对象API(推荐)

放弃全局的plt,每次请求都创建独立的Figure和Axes对象,让每个请求的绘图环境完全隔离,从根源上避免状态共享问题。修改后的代码如下:

from matplotlib.figure import Figure
import io
import base64

# 创建独立的Figure,直接指定尺寸
fig = Figure(figsize=(12, 8))
ax = fig.add_subplot(111)

# 用ax对象完成所有绘图操作,代替全局的plt
ax.set_title("xyz")
ax.plot(x, y, 'b')
ax.plot(x, z, 'r')
fig.tight_layout()

# 将图表保存到BytesIO
buf = io.BytesIO()
fig.savefig(buf, format='png')

# 显式关闭figure释放资源,避免内存泄漏
plt.close(fig)

# 转base64生成HTML可用的图片地址
image_base64 = base64.b64encode(buf.getvalue()).decode('utf-8').replace('\n', '')
img_src = f'data:image/png;base64, {image_base64}'

这种方式是Web环境下使用Matplotlib的最佳实践,完全避开了全局状态的干扰。

方案2:彻底清理全局状态(应急过渡用)

如果暂时不想大规模修改代码,那就要确保每次请求处理完后,彻底清除Matplotlib的全局状态——不止plt.clf(),还要加上plt.close('all')关闭所有残留的Figure对象:

plt.figure()
plt.title("xyz")
plt.tight_layout()
plt.plot(x,y, 'b')
plt.plot(x,z, 'r')
buf = BytesIO()
fig = plt.gcf()
fig.set_size_inches(12,8, forward=True)
fig.savefig(buf, format='png')

# 先清除当前figure内容,再关闭所有figure彻底清理全局状态
plt.clf()
plt.close('all')  # 这行是关键!

image_base64 = base64.b64encode( buf.getvalue()).decode('utf-8').replace('\n', '')
img_src = 'data:image/png;base64, {}'.format(image_base64)

不过这个方案在高并发场景下还是有状态冲突的风险,所以优先推荐方案1。

内容的提问来源于stack exchange,提问作者devired

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 07:24:05