Изображение Matplotlib не отображается в шаблоне Django

У меня есть изображение морского барплота, которое я хотел бы отобразить внутри шаблона django.

Я рассмотрел несколько решений, и мне удалось отобразить изображение с помощью HttpResponse. Однако изображение, которое он отображает, — это всего лишь изображение. То, что я хочу, это изображение сюжета на веб-странице, и вы все равно можете щелкнуть панель навигации, кнопку «Домой» и т. д.

import seaborn as sns
import matplotlib.pyplot as plt
from matplotlib.backends.backend_agg import FigureCanvasAgg
from io import BytesIO
from django.template.loader import render_to_string

В views.py

def top_causal(request):
  # code for data manipulation
  f = plt.figure(figsize=(10, 5))
  ax = sns.barplot(data)
  # labels, title etc...

  FigureCanvasAgg(f)
  buf = BytesIO()
  plt.savefig(buf, format='png)
  plt.close(f)

  # this works
  response = HttpResponse(buf.getvalue(), content_type='image/png')
  return response

  # What I want which is to display the image inside a template(does not work)
  buffer = buf.getvalue()
  content_type = "image/png"
  graphic = (buffer, content_type)
  rendered = render_to_string('top_causal.html', {'graphic': graphic})
  return HttpResponse(rendered)

в top_causal.html

<img src = "data:image/png;base64,{{ graphic|safe }}" alt = "Not working.">

HttpResponse отображает изображение как страницу.

Ответ с использованием render_to_string возвращает это вместо изображения внутри веб-страницы. Я все еще вижу панель навигации.

\x06\x1d\x00\x80kT\xb7n]eee\x95\x18\xff\xe1\x87\x1f$I\xf5\xea\xd5\xb3\x19\xcf\xce\xce.\x11\x9b\x9d\x9d-WWW999U\xb8~\xa7N\x9d$\xfd\xf6\x02\xb2\xb0\xb00IR\x9b6mt\xe4\xc8\x91\x12\xb1G\x8e\x1c\x91\xc5b\xb9\xea\xe7\xe1\xda\xb5k\xa7\xf7\xdf\x7f_\xc5\xc5\xc5:|\xf8\xb0V\xadZ\xa5\xe7\x9f\x7f^\xb5j\xd5\xd2\xd4\xa9S\xafx\xee\xdbo\xbf\xad\x81\x03\x07j\xc9\x92%6\xe3\xb9\xb9\xb9\xe5\xba\x9e\xbau\xeb\xcab\xb1h\xc2\x84\t\x9a0aB\xa91M\x9b6-W\xae\xab\xa9W\xaf\x9e\xaaU\xab\xa6\xbd{\xf7\xaaj\xd5\xaa%\xe6]\\\\\xecR\xe7\xb2;\xef\xbcSqqq\x92~{Q\xde\xbb\xef\xbe\xaby\xf3\xe6\xa9\xb8\xb8X\x8b\x16-\xb2k-\x00\x80\xe3b\x07\x1d\x00\x80k\xd4\xb7o_\xa5\xa4\xa4\x94x\x13w||\xbc\xaaT\xa9\xa2\x90\x90\x10\x9b\xf1\xf7\xdf\x7f\xdfz\x8b\xb5$\x9d;wN[\xb7n-\x11W^\x97o\x8do\xd6\xac\x99ul\xc8\x90!JIIQJJ\x8au\xec\xd7 ...
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
760
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вам нужно преобразовать изображение в массив байтов, закодировать его в base64 и встроить в свой шаблон. Вот как это сделать:

<!DOCTYPE html>
<!--my_template.html-->
<html>
  <div class='section'>
    <div class='flex column plot mt15 mlr15 justify-left align-left'>
      <img src='{{ imuri }}'/>
    </div>
  </div>
</html>
from django.template.loader import get_template

def top_causal(request):

    # .......................
    # Get your plot ready ...
    # .......................

    figure = plt.gcf()
    buf = io.BytesIO()
    figure.savefig(buf, format='png', transparent=True, quality=100, dpi=200)
    buf.seek(0)
    imsrc = base64.b64encode(buf.read())
    imuri = 'data:image/png;base64,{}'.format(urllib.parse.quote(imsrc))
    context = { 'plot': imuri}

    # Now embed that to your template
    template = get_template('my_template.html')
    html = template.render(context=context)

    # Your template is ready to go...

Мне все еще нужно добавить return render(request, 'top_causal.html', context) в конце функции?

Fel 17.07.2019 07:56

Конечно, остальное — это то, что вы делаете, когда рендерите обычный шаблон django, я просто хотел показать суть.

cagrias 17.07.2019 07:57

Я изменил коды так, как они выглядят, но изображение все еще не появляется. Предупреждения, которые я получил, были WARNING: QApplication was not created in the main() thread. и QObject::~QObject: Timers cannot be stopped from another thread, которые появляются в моем командном окне, но веб-сайт все еще работает в обычном режиме. Означает ли это, что мне нужно перезапустить и запустить снова?

Fel 17.07.2019 08:07

Что ж, проблема, с которой вы столкнулись, заключается в том, что matplotlib использует tkinter, который должен работать в основном потоке. Поэтому, если вы рисуете свое изображение в основном потоке или используете многопроцессорные библиотеки заданий, такие как сельдерей и т. д., Это будет работать.

cagrias 17.07.2019 08:10

Мой сервер использует Agg. Как мне перейти в основной поток и построить там сюжет?

Fel 17.07.2019 08:40

Если вы получаете предупреждение QApplication was not created in the main() thread., вы фактически не используете серверную часть agg. Возможно, это тема для нового вопроса, но убедитесь, что matplotlib.use("Agg") поверх кода, прежде чем импортировать pyplot.

ImportanceOfBeingErnest 17.07.2019 12:16
Ответ принят как подходящий

Я отказался от идеи использовать matplotlib и вместо этого использовал Highcharts https://www.highcharts.com/, чтобы построить свой график и отобразить его на веб-странице.

Отображаемые данные были получены с использованием Django ORM и Query API.

Другие вопросы по теме