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

Flask网页展示Matplotlib/Seaborn多图表时出现重叠问题求助

Flask页面多图表重叠问题解决

问题描述

使用Flask构建网页时,单独展示每个图表均正常,但在同一页面同时展示两个图表时出现重叠现象。

相关代码

main.py

@main.route('/filetypebarchart', methods=["GET"])
def filetypebarchart():
    fig1 =plt.figure("1")

    df = pd.read_csv('./export_dataframe.csv') 
 
    df.value_counts()
    fig1 = df.type.value_counts().plot(kind = 'barh').get_figure()
    fig1.savefig('./project/filetypebarchart.png')

    return send_file("filetypebarchart.png",mimetype='img/png')


@main.route('/filetypesum', methods=["GET"])
def filetypesum():
    fig2 = plt.figure("2")

    df = pd.read_csv('./export_dataframe.csv')  
    
    fig2 = sns.barplot(data=df, x="type", y="size", estimator="sum", palette="pastel")
    fig2.figure.savefig('./project/filetypesum.png')

    return send_file("filetypesum.png",mimetype='img/png')

HTML代码

<div> 
  <img src="/filetypebarchart" alt="Chart" height="auto" width="100%">
  <br><br>
  <img src="/filetypesum" alt="Chart" height="auto" width="100%">
</div>

问题原因

Matplotlib默认使用全局绘图状态,连续创建图形时若未显式清理之前的画布,后续绘图操作会叠加到已有画布上,导致图表重叠。此外,原代码中先创建plt.figure()后又重新赋值给绘图返回的figure对象,之前的figure实例未被正确处理,也会引发状态残留问题。

解决方法

方法1:显式清理画布

在每个视图函数结束时关闭当前图形,避免状态残留:

import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
from flask import send_file

@main.route('/filetypebarchart', methods=["GET"])
def filetypebarchart():
    # 创建独立画布和坐标轴
    fig1, ax = plt.subplots()
    df = pd.read_csv('./export_dataframe.csv') 
    df.type.value_counts().plot(kind='barh', ax=ax)
    fig1.savefig('./project/filetypebarchart.png')
    # 关闭画布清理全局状态
    plt.close(fig1)
    return send_file("./project/filetypebarchart.png", mimetype='img/png')


@main.route('/filetypesum', methods=["GET"])
def filetypesum():
    fig2, ax = plt.subplots()
    df = pd.read_csv('./export_dataframe.csv')  
    sns.barplot(data=df, x="type", y="size", estimator="sum", palette="pastel", ax=ax)
    fig2.savefig('./project/filetypesum.png')
    plt.close(fig2)
    return send_file("./project/filetypesum.png", mimetype='img/png')

方法2:使用字节流直接返回(避免本地文件存储)

跳过保存到本地文件的步骤,直接将图形转为字节流返回,既避免文件覆盖、权限等问题,也能减少状态残留风险:

import io
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
from flask import send_file

@main.route('/filetypebarchart', methods=["GET"])
def filetypebarchart():
    fig, ax = plt.subplots()
    df = pd.read_csv('./export_dataframe.csv') 
    df.type.value_counts().plot(kind='barh', ax=ax)
    
    # 将图形写入字节流
    img_io = io.BytesIO()
    fig.savefig(img_io, format='png')
    img_io.seek(0)
    plt.close(fig)
    return send_file(img_io, mimetype='image/png')


@main.route('/filetypesum', methods=["GET"])
def filetypesum():
    fig, ax = plt.subplots()
    df = pd.read_csv('./export_dataframe.csv')  
    sns.barplot(data=df, x="type", y="size", estimator="sum", palette="pastel", ax=ax)
    
    img_io = io.BytesIO()
    fig.savefig(img_io, format='png')
    img_io.seek(0)
    plt.close(fig)
    return send_file(img_io, mimetype='image/png')

关键注意点

  • 始终使用plt.close(fig)显式关闭每个创建的图形,清理Matplotlib的全局状态
  • 推荐使用plt.subplots()同时创建figure和axes对象,更清晰地控制绘图区域
  • 避免重复赋值figure变量(比如原代码中先fig1 = plt.figure()又重新赋值为plot返回的figure)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 20:50:33