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

Flask服务返回Matplotlib图片异常:富格式绘图无法渲染

问题分析与解决方案

嘿,我一眼就看出问题所在了——你在PltGraph里混用了matplotlib的面向对象接口和pyplot状态机,导致绘图和最终输出的不是同一个figure对象,才会返回空白图片。

核心问题拆解

你创建了自己的fig = Figure(),但后面调用plt.plot()、plt.ylabel()这些pyplot函数时,其实是在操作matplotlib自动生成的全局默认figure,而不是你定义的fig。最后你把空的fig传给FigureCanvas,自然输出的是空白图片。

两种可行的解决方法

方法一:全程使用面向对象接口(推荐)

这种方式不依赖全局状态,更适合Web应用的多请求场景,避免不同请求之间的干扰:

class PltGraph(Resource):
    def get(self):
        fig = Figure()
        # 获取子图对象,后续所有操作都基于这个对象
        axis = fig.add_subplot(1, 1, 1)
        
        xs = range(100)
        ys = [random.randint(1, 50) for x in xs]
        axis.plot(xs, ys)
        # 用axis的set_*方法设置标签和标题
        axis.set_ylabel("Y label")
        axis.set_xlabel("X label")
        axis.set_title("x and y")
        
        canvas = FigureCanvas(fig)
        output = BytesIO()
        canvas.print_png(output)
        response = make_response(output.getvalue())
        response.mimetype = 'image/png'
        return response

方法二:如果想继续用pyplot状态机

如果习惯了pyplot的写法,记得要获取当前正在操作的figure,并且在请求结束后清理资源,避免状态残留:

class PltGraph(Resource):
    def get(self):
        # 先清空之前的figure,防止上一次请求的内容残留
        plt.clf()
        
        xs = range(100)
        ys = [random.randint(1, 50) for x in xs]
        plt.plot(xs, ys)
        plt.ylabel("Y label")
        plt.xlabel("X label")
        plt.title("x and y")
        
        # 获取当前正在操作的figure对象
        fig = plt.gcf()
        canvas = FigureCanvas(fig)
        output = BytesIO()
        canvas.print_png(output)
        response = make_response(output.getvalue())
        response.mimetype = 'image/png'
        
        # 关闭figure,释放内存资源
        plt.close(fig)
        return response

额外提醒

在Flask这类多线程/多请求的Web应用中,优先使用面向对象接口会更安全,因为pyplot的全局状态可能会在不同请求之间串数据,导致意想不到的绘图错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 10:03:03