【问题标题】:Generate image on-the-fly using FLask and matplotlib使用 FLask 和 matplotlib 即时生成图像
【发布时间】:2018-11-13 04:43:55
【问题描述】:

我想绘制一张图像,而不必将其保存在静态文件夹中。

我有一个用户 Messa 在此处发布的示例,工作正常:

import io
import random
from flask import Response
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from matplotlib.figure import Figure

@app.route('/plot.png')
def plot_png():
    fig = create_figure()
    output = io.BytesIO()
    FigureCanvas(fig).print_png(output)
    return Response(output.getvalue(), mimetype='image/png')

def create_figure():
    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)
    return fig

然后在 HTML 文件中:

<img src="/plot.png" alt="my plot">

结果是完美的。我可以即时获取图像。

现在我想使用一些像这样的参数:

@app.route('/<x_values_source>/<y_values_source>/plot.png')
def plot_png(x_values_source, y_values_source):
    fig = create_figure(x_values_source, y_values_source)
    output = io.BytesIO()
    FigureCanvas(fig).print_png(output)
    return Response(output.getvalue(), mimetype='image/png')

def create_figure(x_values_source, y_values_source):
    x_values = function_that_returns_x_values_set(x_values_source)
    y_values = function_that_returns_y_values_set(y_values_source)
    fig = Figure()
    axis = fig.add_subplot(1, 1, 1)
    axis.plot(x_values, y_values)
    return fig

但当然它不起作用。我对 Python 还很陌生,我还在学习很多东西。

谢谢!

【问题讨论】:

    标签: python matplotlib flask


    【解决方案1】:

    要传入参数,最好不要将它们作为 URI 的前缀,因为这可能会混淆 Flask 的路由解码。相反,如果你形成这样的 URL

    /plot.png?x=1,2,3,4&y=100,200,300,400
    

    您可以通过request.args 获取参数。它们将以字符串形式出现,因此您需要将它们分开并转换为整数(或浮点数,如果您使用的是实数)

    from flask import request
    
    @app.route('/plot.png')
    def plot():
        try:
            x_values = [int(x) for x in request.args.get('x','').split(',')]
            y_values = [int(y) for y in request.args.get('y','').split(',')]
        except:
            # malformed 
    

    我有一个工作示例here 动态处理 matplotlib 的稳健方法。总体思路是

    from flask import send_file
    
    @app.route('/plot.png')
    def plot_png():
        fig, ax = plt.subplots()
        draw(ax)
        return fig_response(fig)
    
    def fig_response(fig):
        """Turn a matplotlib Figure into Flask response"""
        img_bytes = BytesIO()
        fig.savefig(img_bytes)
        img_bytes.seek(0)
        return send_file(img_bytes, mimetype='image/png')
    

    您在哪里提供draw()。不过,请看一下我的示例,因为您需要添加一些缓存标头。

    【讨论】:

    • 嗨!谢谢回复。我仍然看不到如何通过路由发送参数。
    • 谢谢!我会试一试。为了更清楚,我还修改了我原来的问题。
    猜你喜欢
    • 2017-02-18
    • 2021-09-17
    • 1970-01-01
    • 1970-01-01
    • 2012-09-05
    • 2015-05-28
    • 1970-01-01
    • 1970-01-01
    • 2021-04-01
    相关资源
    最近更新 更多