Матплотлиб с колбой

#python #html #matplotlib #flask #backend

Вопрос:

Я пытаюсь отобразить график, который я сделал в Matplotlib, в приложении Flask. Однако, когда я запускаю приложение на локальном хосте, оно не отображает изображение графика, и появляется только значок изображения с фразой «Динамическое изображение».

Скриншот

Это мой код:

 import io
import matplotlib.pyplot as plt
from numpy import *
from flask import Flask, render_template, make_response

app = Flask(__name__)

plt.style.use("fivethirtyeight")


@app.route("/simple.png")
def simple_image():
    def beta1(x, y):
        term1 = x - average(x)
        term2 = y - average(y)
        Sxy = sum(term1 * term2)
        Sxx = sum(term1 * term1)
        return Sxy / Sxx

    def beta0(x, y):
        return average(y) - beta1(x, y) * average(x)

    def plot_recta(x, y):
        b1 = beta1(x, y)
        b0 = beta0(x, y)
        pnts_x = linspace(x[0], x[-1], 100)
        pnts_y = b0   b1 * pnts_x
        plt.plot(pnts_x, pnts_y)
        plt.plot(x, y, "r*")
        plt.show()

    x = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,
         18,19,20,21,22,23,24,25,26,27,28,29,30]
    y = (334,2203,9993,4626,3961,3943,938,4744,4881,5624,
         675,8091,3680,4090,66,9479,9117,2759,7270,7849,
         1093,7508,2737,5062,3032,2541,9445,4440,7192,6746)

    num_y = int(len(y))

    if num_y >= 10:
        plot_recta(x, y)

    else:
        print("You need more than 10 values to make a prediction")
    buffer = io.BytesIO()
    plt.savefig(buffer, format="png")
    buffer.seek(0)
    plt.close()

    response = make_response(buffer.getvalue())
    response.mimetype = "image/png"

    return response


@app.route("/")
def index():
    return render_template("index.html", title="Your progress")


if __name__ == "__main__":
    import sys

    app.run(debug="d" in sys.argv[-1])
 

А HTML-шаблон такой:

 <html>
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>{{ title }}</title>
  </head>
  <body>
    <h1>{{ title }}</h1>
    <img src="/simple.png" alt="Dynamic Image" />
  </body>
</html>
 

Комментарии:

1. вы увидите ошибку(ошибка потоковой передачи) в журнале flask. вам нужно будет прокомментировать, plt.show() так как в этом нет необходимости.

Ответ №1:

Возможно, переключитесь на использование matplotlib с объектно-ориентированным интерфейсом. Вот так:

 import io
import matplotlib

matplotlib.use("agg")
import matplotlib.pyplot as plt
import numpy as np
from flask import Flask, render_template, make_response

app = Flask(__name__)
plt.style.use("fivethirtyeight")

@app.route("/simple.png")
def simple_image():
    fig, ax = plt.subplots()
    x = np.arange(0, 4 * np.pi, 0.1)
    ax.plot(x, np.sin(x))
    buffer = io.BytesIO()
    fig.savefig(buffer, format="png")
    buffer.seek(0)

    response = make_response(buffer.getvalue())
    response.mimetype = "image/png"
    return response

@app.route("/")
def index():
    return render_template("index.html", title="Your progress")

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

введите описание изображения здесь