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

如何用Flask在表单同页面展示Matplotlib生成的图表?

当然可以呀!其实只需要调整下你的Flask逻辑和前端模板,就能实现表单和图表在同一页面共存,用户改完参数提交后直接刷新图表就行。我给你梳理下具体的实现步骤和代码示例:

核心思路

让表单和图表在同一个页面渲染:

  • 用户首次访问页面时,只显示表单
  • 用户提交参数后,后端生成图表并转为Base64字符串传给模板,模板同时渲染表单和更新后的图表
具体实现步骤

1. 调整Flask后端代码

我们要处理图表的生成和转码,避免生成本地图片文件,直接把图表转为Base64嵌入HTML,这样更简洁高效:

from flask import Flask, request, render_template
import matplotlib.pyplot as plt
from io import BytesIO
import base64

app = Flask(__name__)

# 设置Matplotlib非交互式后端,避免Flask运行时出现GUI相关错误
plt.switch_backend('AGG')

def generate_chart(param1, param2):
    # 这里替换成你自己的图表生成逻辑,用用户传入的参数
    plt.figure(figsize=(8, 5))
    plt.plot([1, 2, 3, 4], [param1, param2, param1+param2, param1*param2])
    plt.title('用户参数生成的图表')
    plt.xlabel('X轴')
    plt.ylabel('Y轴')
    
    # 将图表转为Base64字符串,方便嵌入HTML
    img_buffer = BytesIO()
    plt.savefig(img_buffer, format='png')
    img_buffer.seek(0)
    img_base64 = base64.b64encode(img_buffer.getvalue()).decode('utf-8')
    plt.close()  # 关闭图表释放内存,避免内存泄漏
    return img_base64

@app.route('/', methods=['GET', 'POST'])
def index():
    chart_data = None
    # 处理表单提交的参数(这里假设表单有param1和param2两个参数)
    if request.method == 'POST':
        param1 = float(request.form.get('param1', 1))
        param2 = float(request.form.get('param2', 2))
        chart_data = generate_chart(param1, param2)
    
    # 不管是首次访问还是提交后,都渲染同一个模板,把图表数据(如果有的话)传过去
    return render_template('index.html', chart_data=chart_data)

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

2. 编写前端模板(templates/index.html)

模板里同时包含表单区域和图表展示区域,根据是否有chart_data来决定是否显示图表,还会保留用户上次提交的参数,提升体验:

<!DOCTYPE html>
<html>
<head>
    <title>参数查询与图表展示</title>
    <style>
        .container {
            max-width: 800px;
            margin: 20px auto;
            padding: 0 20px;
        }
        .form-group {
            margin-bottom: 15px;
        }
        label {
            display: block;
            margin-bottom: 5px;
        }
        input {
            width: 100%;
            padding: 8px;
            box-sizing: border-box;
        }
        button {
            padding: 10px 20px;
            background-color: #007bff;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
        }
        .chart-container {
            margin-top: 30px;
            padding-top: 20px;
            border-top: 1px solid #eee;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>参数查询与图表展示</h1>
        <!-- 表单区域 -->
        <form method="POST">
            <div class="form-group">
                <label for="param1">参数1:</label>
                <input type="number" id="param1" name="param1" value="{{ request.form.get('param1', 1) }}" step="0.1">
            </div>
            <div class="form-group">
                <label for="param2">参数2:</label>
                <input type="number" id="param2" name="param2" value="{{ request.form.get('param2', 2) }}" step="0.1">
            </div>
            <button type="submit">生成/更新图表</button>
        </form>

        <!-- 图表展示区域 -->
        {% if chart_data %}
        <div class="chart-container">
            <h3>生成的图表</h3>
            <img src="data:image/png;base64,{{ chart_data }}" alt="用户生成的图表" style="max-width:100%;">
        </div>
        {% else %}
        <div class="chart-container">
            <p>请填写参数并点击按钮查看图表结果</p>
        </div>
        {% endif %}
    </div>
</body>
</html>
关键细节说明
  • Base64转码:直接把Matplotlib图表转为Base64字符串嵌入HTML,不需要在服务器保存图片文件,省去了文件管理的麻烦。
  • 参数保留:模板里用{{ request.form.get('param1', 1) }}保留用户上次提交的参数,用户修改时不用重新输入全部内容,体验更流畅。
  • 内存管理:plt.close()一定要加,避免Matplotlib的图表对象占用过多内存,尤其是在用户频繁提交的场景下。
  • 非交互式后端:plt.switch_backend('AGG')是为了适配服务器环境(通常没有图形界面),避免出现Matplotlib的GUI错误。

这样调整后,用户访问页面时先看到表单,提交后表单依然在页面上方,下方显示生成的图表;修改参数再次提交,图表会实时更新,完全符合你的需求~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 04:15:40