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

Flask中Matplotlib生成图片页面显示异常问题求助

问题:Matplotlib生成的PNG图片在Web页面显示异常,新窗口打开正常

我正在开发Web应用,需展示API生成的图片:API将Matplotlib图表转为PNG后通过io库发送给主应用。页面上的图片几乎总是显示异常,但右键在新窗口打开则显示正常。

异常图片:
损坏的图片

发送图表的API代码:

@app.route('/send-data-a', methods=['GET'])
def send_data_user_dynamic():
    # ...生成图表的代码...
    image_stream1 = io.BytesIO()
    plt.savefig(image_stream1, format='png')
    image_stream1.seek(0)
    plt.close(fig)
    return send_file(image_stream1, mimetype='image/png')

主应用代码(曾尝试添加时间戳使链接唯一,无效):

@app.route('/data', methods=['GET'])
def data():
    timestamp = int(time.time())
    user_dynamic = requests.get(f'http://127.0.0.1:5000/send-data-a?timestamp={timestamp}')
    user_amount = requests.get(f'http://127.0.0.1:5000/send-data-b?timestamp={timestamp}')
    kp_month = requests.get(f'http://127.0.0.1:5000/send-data-c?timestamp={timestamp}')
    kp_week = requests.get(f'http://127.0.0.1:5000/send-data-d?timestamp={timestamp}')
    return render_template('second.html',
                           user_dynamic=user_dynamic.url,
                           user_amount=user_amount.url,
                           kp_month=kp_month.url,
                           kp_week=kp_week.url)

if __name__ == '__main__':
    app.run(debug=True, port=5001)

HTML模板代码:

<div class="diagram">
    <img src="{{ user_dynamic }}" alt="user_dynamic">
    <figcaption>some text</figcaption>
</div>
解决方案
  • 核心问题:重复请求导致流读取异常
    你当前主应用用requests.get提前请求了图片API,但只把URL传给模板,这会让API被请求两次:一次是主应用的请求,一次是浏览器加载<img>的请求。BytesIO流在第一次读取后位置会偏移,第二次请求返回的就是损坏的数据。

  • 修复步骤:

    1. 修改主应用代码,直接构造URL传递给模板
      去掉提前发起的requests.get,直接生成URL:

      @app.route('/data', methods=['GET'])
      def data():
          timestamp = int(time.time())
          # 直接构造URL,不提前请求API
          user_dynamic = f'http://127.0.0.1:5000/send-data-a?timestamp={timestamp}'
          user_amount = f'http://127.0.0.1:5000/send-data-b?timestamp={timestamp}'
          kp_month = f'http://127.0.0.1:5000/send-data-c?timestamp={timestamp}'
          kp_week = f'http://127.0.0.1:5000/send-data-d?timestamp={timestamp}'
          return render_template('second.html',
                                 user_dynamic=user_dynamic,
                                 user_amount=user_amount,
                                 kp_month=kp_month,
                                 kp_week=kp_week)
      
    2. 优化API的send_file参数
      添加缓存控制和文件名参数,确保浏览器正确识别资源:

      return send_file(
          image_stream1,
          mimetype='image/png',
          attachment_filename='user_dynamic.png',
          cache_timeout=0  # 禁用缓存
      )
      
    3. 彻底清理Matplotlib资源
      避免残留图表影响后续生成:

      plt.savefig(image_stream1, format='png')
      image_stream1.seek(0)
      plt.close(fig)
      plt.clf()  # 清空当前图表
      plt.close('all')  # 关闭所有图表窗口
      
    4. 添加禁止缓存的响应头(可选)
      进一步防止浏览器缓存旧图片:

      from flask import make_response
      
      # ...生成流的代码...
      response = make_response(send_file(image_stream1, mimetype='image/png', cache_timeout=0))
      response.headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0'
      response.headers['Pragma'] = 'no-cache'
      return response
      

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 20:13:17