Передача фигуры matplotlib в HTML (колбу)
Я использую matplotlib для отображения некоторой фигуры в веб-приложении. Я использовал fig.savefig()
раньше, когда я просто запускаю скрипты. Тем не менее, мне нужна функция, чтобы вернуть фактическое ".png" изображение, чтобы я мог вызвать его с помощью моего HTML.
Еще одна (возможно, ненужная) информация: я использую Python Flask. Я полагаю, что могу использовать fig.savefig()
и просто вставлять фигуру в свою статическую папку, а затем вызывать ее из своего HTML, но я бы не стал делать это каждый раз. Было бы оптимально, если бы я мог просто создать фигуру, сделать из нее изображение, вернуть это изображение и называть его из моего HTML, а затем он уходит.
Код, который создает фигуру, работает. Тем не менее, он возвращает фигуру, которая не работает с HTML, я думаю.
Здесь, где я вызываю draw_polygon
в маршрутизации, draw_polygon
- это метод, который возвращает фигуру:
@app.route('/images/<cropzonekey>')
def images(cropzonekey):
fig = draw_polygons(cropzonekey)
return render_template("images.html", title=cropzonekey, figure = fig)
И вот HTML, где я пытаюсь сгенерировать изображение.
<html>
<head>
<title>{{ title }} - image</title>
</head>
<body>
<img src={{ figure }} alt="Image Placeholder" height="100">
</body>
</html>
И, как вы можете догадаться, когда я загружаю страницу, все, что я получаю, это Image Placeholder
. Таким образом, им не понравился формат, которым я кормил фигуру.
Кто-нибудь знает, какие методы matplotlib/work-arounds превращают фигуру в фактическое изображение? Я все эти документы, но ничего не могу найти. Спасибо!
BTW: не думал, что нужно включить код python, который делает фигуру, но я могу включить ее, если вам, ребята, нужно это увидеть (просто не захотелось загромождать вопрос)
Ответы
Ответ 1
Вы должны разделить HTML и изображение на два разных маршрута.
Ваш маршрут /images/<cropzonekey>
будет просто обслуживать страницу, а в содержимом HTML этой страницы будет ссылка на второй маршрут, тот, который служит для изображения.
Изображение подается по собственному маршруту из файла памяти, который вы создаете с помощью savefig()
.
Я, очевидно, не тестировал это, но я считаю, что следующий пример будет работать так, как есть или приблизится к рабочему решению:
@app.route('/images/<cropzonekey>')
def images(cropzonekey):
return render_template("images.html", title=cropzonekey)
@app.route('/fig/<cropzonekey>')
def fig(cropzonekey):
fig = draw_polygons(cropzonekey)
img = StringIO()
fig.savefig(img)
img.seek(0)
return send_file(img, mimetype='image/png')
Ваш шаблон images.html
становится:
<html>
<head>
<title>{{ title }} - image</title>
</head>
<body>
<img src="{{ url_for('fig', cropzonekey = title) }}" alt="Image Placeholder" height="100">
</body>
</html>
Ответ 2
Я работаю с Python 3.x, я изменил некоторые строки кода, и это сработало для меня. У меня появилось следующее сообщение об ошибке: "..... объект не имеет атрибута" savefig "
@app.route('/fig/<cropzonekey>')
def fig(cropzonekey):
#fig = draw_polygons(cropzonekey)
fig = plt.plot([1,2,3,4], [1,2,3,4])
#img = StringIO()
img = BytesIO()
#fig.savefig(img)
plt.savefig(img)
img.seek(0)
return send_file(img, mimetype='image/png')